প্রথমে আলসামির উত্তর আপভোট করুন। এটি আমাকে সঠিক পথে পেয়েছে।
তবে আপনারা যারা আইওসি করছেন তাদের জন্য এখানে কিছুটা গভীর ডাইভ রয়েছে।
আমার ত্রুটি (অন্যদের মতো)
এক বা একাধিক ত্রুটি ঘটেছে। (একটি দ্বিতীয় অপারেশন পূর্ববর্তী অপারেশন সম্পন্ন করার আগে এই প্রেক্ষাপটে শুরু। সাধারণত বিভিন্ন থ্রেড DbContext একই উদাহরণস্বরূপ ব্যবহার দ্বারা ঘটিত হয়। কিভাবে DbContext সমস্যা থ্রেডিং এড়াতে সম্পর্কে আরো তথ্যের জন্য, দেখুন
https://go.microsoft.com / fwlink /? linkid = 2097913। )
আমার কোড সেটআপ। "শুধু বেসিক" ...
public class MyCoolDbContext: DbContext{
public DbSet <MySpecialObject> MySpecialObjects { get; set; }
}
এবং
public interface IMySpecialObjectDomainData{}
এবং (নোট মাইকুলডিবি কনটেক্সট ইনজেকশন দেওয়া হচ্ছে)
public class MySpecialObjectEntityFrameworkDomainDataLayer: IMySpecialObjectDomainData{
public MySpecialObjectEntityFrameworkDomainDataLayer(MyCoolDbContext context) {
this.entityDbContext = context ?? throw new ArgumentNullException("MyCoolDbContext is null", (Exception)null);
}
}
এবং
public interface IMySpecialObjectManager{}
এবং
public class MySpecialObjectManager: IMySpecialObjectManager
{
public const string ErrorMessageIMySpecialObjectDomainDataIsNull = "IMySpecialObjectDomainData is null";
private readonly IMySpecialObjectDomainData mySpecialObjectDomainData;
public MySpecialObjectManager(IMySpecialObjectDomainData mySpecialObjectDomainData) {
this.mySpecialObjectDomainData = mySpecialObjectDomainData ?? throw new ArgumentNullException(ErrorMessageIMySpecialObjectDomainDataIsNull, (Exception)null);
}
}
এবং অবশেষে, আমার বহু থ্রেড ক্লাস, একটি কনসোল অ্যাপ (কমান্ড লাইন ইন্টারফেস অ্যাপ) থেকে কল করা হচ্ছে
public interface IMySpecialObjectThatSpawnsThreads{}
এবং
public class MySpecialObjectThatSpawnsThreads: IMySpecialObjectThatSpawnsThreads
{
public const string ErrorMessageIMySpecialObjectManagerIsNull = "IMySpecialObjectManager is null";
private readonly IMySpecialObjectManager mySpecialObjectManager;
public MySpecialObjectThatSpawnsThreads(IMySpecialObjectManager mySpecialObjectManager) {
this.mySpecialObjectManager = mySpecialObjectManager ?? throw new ArgumentNullException(ErrorMessageIMySpecialObjectManagerIsNull, (Exception)null);
}
}
এবং ডিআই বিল্ডআপ। (আবার এটি কনসোল অ্যাপ্লিকেশনটির জন্য (কমান্ড লাইন ইন্টারফেস) ... যা ওয়েব-অ্যাপ্লিকেশনগুলির তুলনায় কিছুটা ভিন্ন আচরণ দেখায়)
private static IServiceProvider BuildDi(IConfiguration configuration) {
string defaultConnectionStringValue = string.Empty;
IServiceCollection servColl = new ServiceCollection()
.AddTransient<IMySpecialObjectDomainData, MySpecialObjectEntityFrameworkDomainDataLayer>()
.AddTransient<IMySpecialObjectManager, MySpecialObjectManager>()
# if (MY_ORACLE)
.AddDbContext<ProvisioningDbContext>(options => options.UseOracle(defaultConnectionStringValue), ServiceLifetime.Transient);
# endif
# if (MY_SQL_SERVER)
.AddDbContext<ProvisioningDbContext>(options => options.UseSqlServer(defaultConnectionStringValue), ServiceLifetime.Transient);
# endif
servColl.AddSingleton <IMySpecialObjectThatSpawnsThreads, MySpecialObjectThatSpawnsThreads>();
ServiceProvider servProv = servColl.BuildServiceProvider();
return servProv;
}
যেগুলি আমাকে বিস্মিত করেছিল তারা হ'ল (পরিবর্তিত) জন্য ক্ষণস্থায়ী
.AddTransient<IMySpecialObjectDomainData, MySpecialObjectEntityFrameworkDomainDataLayer>()
.AddTransient<IMySpecialObjectManager, MySpecialObjectManager>()
দ্রষ্টব্য, আমি মনে করি যেহেতু আইএমআইস্পেশিয়ালঅবজেক্টম্যানেজারকে "মাইস্পেশিয়ালবজেক্টট্যাটস্পেনস ট্র্যাডস" ইনজেক্ট করা হয়েছিল, সেই ইঞ্জেকশনযুক্ত বিষয়গুলি চেইনটি সম্পূর্ণ করার জন্য ট্রান্সিয়েন্ট হওয়া দরকার।
বিষয়টি হ'ল ....... এটি কেবল (আমার) ডিবি কনটেক্সটই ছিল না যা প্রয়োজন rans ট্রান্সিয়েন্ট ... তবে ডিআই গ্রাফের একটি বড় অংশ।
ডিবাগিং টিপ:
এই লাইন:
this.entityDbContext = context ?? throw new ArgumentNullException("MyCoolDbContext is null", (Exception)null);
আপনার ডিবাগার ব্রেক পয়েন্টটি সেখানে রাখুন। যদি আপনার মাইস্পেশিয়ালঅবজেক্টট্যাটস্প্যানস থ্রেডগুলি এন সংখ্যায় থ্রেড তৈরি করে (উদাহরণস্বরূপ 10 টি থ্রেড বলুন) ...... এবং সেই লাইনটি কেবল একবার আঘাত করা হবে ... এটি আপনার সমস্যা। আপনার DbContext থ্রেড অতিক্রম করছে।
বোনাস:
আমি এই নীচের url / আর্টিকেলটি পড়ার পরামর্শ দেব (পুরাতন তবে গুডি) পার্থক্যগুলি ওয়েব-অ্যাপস এবং কনসোল-অ্যাপস সম্পর্কে about
https://mehdi.me/ambient-dbcontext-in-ef6/
লিঙ্ক পরিবর্তিত হয় নিবন্ধের শিরোনাম এখানে।
এন্টিটির ফ্রেম ওয়ার্কের সাথে সঠিকভাবে ডব্লিকন্টেক্সট পরিচালনা করা:: একটি ইন-ডেপথ গাইড মেহদি এল গুয়েদারি
আমি এই সমস্যাটিকে ওয়ার্কফ্লোকোর https://github.com/danielgerlag/workflow-core দিয়ে আঘাত করেছি
<ItemGroup>
<PackageReference Include="WorkflowCore" Version="3.1.5" />
</ItemGroup>
নীচে নমুনা কোড .. ভবিষ্যতের ইন্টারনেট অনুসন্ধানকারীদের সহায়তা করার জন্য
namespace MyCompany.Proofs.WorkFlowCoreProof.BusinessLayer.Workflows.MySpecialObjectInterview.Workflows
{
using System;
using MyCompany.Proofs.WorkFlowCoreProof.BusinessLayer.Workflows.MySpecialObjectInterview.Constants;
using MyCompany.Proofs.WorkFlowCoreProof.BusinessLayer.Workflows.MySpecialObjectInterview.Glue;
using MyCompany.Proofs.WorkFlowCoreProof.BusinessLayer.Workflows.WorkflowSteps;
using WorkflowCore.Interface;
using WorkflowCore.Models;
public class MySpecialObjectInterviewDefaultWorkflow : IWorkflow<MySpecialObjectInterviewPassThroughData>
{
public const string WorkFlowId = "MySpecialObjectInterviewWorkflowId";
public const int WorkFlowVersion = 1;
public string Id => WorkFlowId;
public int Version => WorkFlowVersion;
public void Build(IWorkflowBuilder<MySpecialObjectInterviewPassThroughData> builder)
{
builder
.StartWith(context =>
{
Console.WriteLine("Starting workflow...");
return ExecutionResult.Next();
})
.Then(lastContext =>
{
Console.WriteLine();
bool wroteConcreteMsg = false;
if (null != lastContext && null != lastContext.Workflow && null != lastContext.Workflow.Data)
{
MySpecialObjectInterviewPassThroughData castItem = lastContext.Workflow.Data as MySpecialObjectInterviewPassThroughData;
if (null != castItem)
{
Console.WriteLine("MySpecialObjectInterviewDefaultWorkflow complete :) {0} -> {1}", castItem.PropertyOne, castItem.PropertyTwo);
wroteConcreteMsg = true;
}
}
if (!wroteConcreteMsg)
{
Console.WriteLine("MySpecialObjectInterviewDefaultWorkflow complete (.Data did not cast)");
}
return ExecutionResult.Next();
}))
.OnError(WorkflowCore.Models.WorkflowErrorHandling.Retry, TimeSpan.FromSeconds(60));
}
}
}
এবং
ICollection<string> workFlowGeneratedIds = new List<string>();
for (int i = 0; i < 10; i++)
{
MySpecialObjectInterviewPassThroughData currentMySpecialObjectInterviewPassThroughData = new MySpecialObjectInterviewPassThroughData();
currentMySpecialObjectInterviewPassThroughData.MySpecialObjectInterviewPassThroughDataSurrogateKey = i;
string wfid = await this.workflowHost.StartWorkflow(MySpecialObjectInterviewDefaultWorkflow.WorkFlowId, MySpecialObjectInterviewDefaultWorkflow.WorkFlowVersion, currentMySpecialObjectInterviewPassThroughData);
workFlowGeneratedIds.Add(wfid);
}