C# 不同DBContext上的异步任务。说第二次手术是在这种情况下开始的 公共静态异步void DoSomething(IEnumerable dbContexts) { IEnumerator dbContextEnumerator=dbContexts.GetEnumerator(); Task projectSchemaTask=Task.Run(()=>Core.Data.ProjectRead .GetAll(dbContextEnumerator.Current) .其中(a=>a.PJrecid==PJrecid) .选择(b=>newprojectschema { PJtextid=b.PJtextid, PJcustomerid=b.PJcustomerid, PJininvoiceable=b.PJininvoiceable, PJselfmanning=b.PJselfmanning, PJcategory=b.PJcategory }) .FirstOrDefault()); 任务defaultActivitySchemeTask=projectSchemaTask.ContinueWith(先行项=> { //这是可能引发异常的地方 返回ProjectTypeRead.GetAll(dbContextEnumerator.Current) .Where(a=>a.PTid==antecedent.Result.PJcategory) .选择(a=>a.PTactivitySchemeID) .FirstOrDefaultAsync().Result; },TaskContinuationOptions。仅限OnArntoCompletion); 任务customerTask=projectSchemaTask.ContinueWith((先行项)=> { //这是可能引发异常的地方 返回GetCustomerDataAsync(antecedent.Result.PJcustomerid, dbContextEnumerator.Current)。结果; },TaskContinuationOptions。仅限OnArntoCompletion); wait Task.WhenAll(defaultActivitySchemeTask,customerTask); }
我得到的例外情况是: NotSupportedException:在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在此上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全 该异常仅在大约每1/20次调用该函数时抛出。只有当我将任务链接到C# 不同DBContext上的异步任务。说第二次手术是在这种情况下开始的 公共静态异步void DoSomething(IEnumerable dbContexts) { IEnumerator dbContextEnumerator=dbContexts.GetEnumerator(); Task projectSchemaTask=Task.Run(()=>Core.Data.ProjectRead .GetAll(dbContextEnumerator.Current) .其中(a=>a.PJrecid==PJrecid) .选择(b=>newprojectschema { PJtextid=b.PJtextid, PJcustomerid=b.PJcustomerid, PJininvoiceable=b.PJininvoiceable, PJselfmanning=b.PJselfmanning, PJcategory=b.PJcategory }) .FirstOrDefault()); 任务defaultActivitySchemeTask=projectSchemaTask.ContinueWith(先行项=> { //这是可能引发异常的地方 返回ProjectTypeRead.GetAll(dbContextEnumerator.Current) .Where(a=>a.PTid==antecedent.Result.PJcategory) .选择(a=>a.PTactivitySchemeID) .FirstOrDefaultAsync().Result; },TaskContinuationOptions。仅限OnArntoCompletion); 任务customerTask=projectSchemaTask.ContinueWith((先行项)=> { //这是可能引发异常的地方 返回GetCustomerDataAsync(antecedent.Result.PJcustomerid, dbContextEnumerator.Current)。结果; },TaskContinuationOptions。仅限OnArntoCompletion); wait Task.WhenAll(defaultActivitySchemeTask,customerTask); },c#,.net,asynchronous,task,dbcontext,C#,.net,Asynchronous,Task,Dbcontext,我得到的例外情况是: NotSupportedException:在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在此上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全 该异常仅在大约每1/20次调用该函数时抛出。只有当我将任务链接到ContinueWith()时,才会出现异常 当我为每个请求使用一个新的操作时,如何在上下文上有第二个操作 这只是我代码的一个示例。在实际代码中,我有3个父任务,每个父任务都有1-5个链接任务 我做错了什么?是
ContinueWith()
时,才会出现异常
当我为每个请求使用一个新的操作时,如何在上下文上有第二个操作
这只是我代码的一个示例。在实际代码中,我有3个父任务,每个父任务都有1-5个链接任务
我做错了什么?是的,这些天你基本上不应该继续使用
;在这种情况下,您将在同一任务上完成两个连续任务(对于defaultActivitySchemeTask
和customerTask
);它们之间的交互方式现在基本上还没有定义,这将取决于两个异步流的工作方式,但在这里,您完全可能会遇到重叠的异步操作(例如,在最简单的“continuations is sequential”中,只要第一个操作因为不完整而等待,第二个操作就会启动)。坦率地说,这应该是逻辑上连续的wait
代码,可能不使用Task。也运行,但我们暂时保留它:
ProjectSchema ProjectSchema=wait Task.Run(()=>…);
智力?defaultActivityScheme=等待。。。第一位
SomeModel客户=等待。。。第二位
我们不能同时执行两个下级查询,而不冒在同一上下文上进行并发异步操作的风险。是的,现在基本上不应该使用ContinueWith
;在这种情况下,您将在同一任务上完成两个连续任务(对于defaultActivitySchemeTask
和customerTask
);它们之间的交互方式现在基本上还没有定义,这将取决于两个异步流的工作方式,但在这里,您完全可能会遇到重叠的异步操作(例如,在最简单的“continuations is sequential”中,只要第一个操作因为不完整而等待,第二个操作就会启动)。坦率地说,这应该是逻辑上连续的wait
代码,可能不使用Task。也运行,但我们暂时保留它:
ProjectSchema ProjectSchema=wait Task.Run(()=>…);
智力?defaultActivityScheme=等待。。。第一位
SomeModel客户=等待。。。第二位
我们不能同时执行两个从属查询,而不冒在同一上下文上执行并发异步操作的风险。在您的示例中,您似乎并行运行两个continuation,因此它们可能重叠,从而导致并发问题DbContext
不是线程安全的,因此需要确保异步调用是顺序的。请记住,使用async
/await
只需将代码转换为状态机,这样您就可以在转到下一个操作之前控制哪些操作已完成。单独使用异步方法不能确保并行操作,但可以将操作包装在任务中。运行将确保并行操作。因此,您需要问问自己,这是任务。运行是真正需要的(即在线程池中安排工作)以使其并行
您提到,在实际代码中,您有3个父任务,每个父任务都有1-5个链接任务附加到它们。如果这3个父任务具有单独的DBContext,则它们可以并行运行(每个任务都包装在Task.run
中),但它们的链接延续需要是连续的(利用异步/等待关键字)。就像这样:
public异步任务DoWork()
{
var parentTask1=Task.Run(parentTask1);
var parentTask2=Task.Run(parentTask2);
var parentTask3=Task.Run(parentTask3);
等待任务。WhenAll(parentTask1、parentTask2、parentTask3);
}
专用异步任务ParentTask1()
{
//链式子异步延续
等待任务。延迟(100);
等待任务。延迟(100);
}
专用异步任务ParentTask2()
{
//链式子异步延续
等待任务。延迟(100);
等待任务。延迟(100);
}
专用异步任务ParentTask3()
{
public static async void DoSomething(IEnumerable<IDbContext> dbContexts)
{
IEnumerator<IDbContext> dbContextEnumerator = dbContexts.GetEnumerator();
Task<ProjectSchema> projectSchemaTask = Task.Run(() => Core.Data.ProjectRead
.GetAll(dbContextEnumerator.Current)
.Where(a => a.PJrecid == pjRecId)
.Select(b => new ProjectSchema
{
PJtextid = b.PJtextid,
PJcustomerid = b.PJcustomerid,
PJininvoiceable = b.PJininvoiceable,
PJselfmanning = b.PJselfmanning,
PJcategory = b.PJcategory
})
.FirstOrDefault());
Task<int?> defaultActivitySchemeTask = projectSchemaTask.ContinueWith(antecedent =>
{
//This is where an exception may get thrown
return ProjectTypeRead.GetAll(dbContextEnumerator.Current)
.Where(a => a.PTid == antecedent.Result.PJcategory)
.Select(a => a.PTactivitySchemeID)
.FirstOrDefaultAsync().Result;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
Task<SomeModel> customerTask = projectSchemaTask.ContinueWith((antecedent) =>
{
//This is where an exception may get thrown
return GetCustomerDataAsync(antecedent.Result.PJcustomerid,
dbContextEnumerator.Current).Result;
}, TaskContinuationOptions.OnlyOnRanToCompletion);
await Task.WhenAll(defaultActivitySchemeTask, customerTask);
}