首页 > 解决方案 > ASP.NET Core Task.WhenAll - 在前一个操作完成之前在此上下文上启动了第二个操作

问题描述

我开始尝试将我的数据库查询转换为异步的,但我真的不明白如何正确地做到这一点。

我现在收到错误:

在前一个操作完成之前,在此上下文上开始了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的。有关如何避免 DbContext 线程问题的更多信息

public async Task<IList<MyObject>> GetAll(MyContext context)
    {
        
   return (await Task.WhenAll(
    MethodA(context), MethodB(context)))
    .SelectMany(e => e)
    .ToList();
}

 private async Task<IList<MyObject>> MethodA(MyContext context)
    {
    
    
 return await context.MyThings.Include(x => x.Stuff)
    
 //full query removed for readability 
.ToListAsync();
    
}

 private async Task<IList<MyObject>> MethodB(MyContext context)
    {
    
    
 return await context.MyThings.Include(x => x.Stuff)
    
 //full query removed for readability 
.ToListAsync();
    
}

索引.cs:

public Task<IList<MyObject>> MyDBList  { get; set; }

public void OnGet()
    {
    
        MyDBList = _myInterface.GetAll_context);

}

索引.cshml


     @foreach (var x in Model.MyDBList)
    {
<p>x.ID</p>
}

我厌倦了使 dbcontext 瞬态,但这没有任何区别。我也担心它会破坏我更新数据库中条目的许多其他代码。

我可以看到为什么会发生错误,我在同一个上下文中运行两个查询,但我不知道如何修复它。

任何人都可以建议吗?

标签: entity-frameworkasp.net-core-3.1

解决方案


我可以看到为什么会发生错误,我在同一个上下文中运行两个查询,但我不知道如何修复它。

修复它的最简单方法是一次只运行一个查询:

public async Task<IList<MyObject>> GetAll(MyContext context)
{
  var resultsA = await MethodA(context);
  var resultsB = await MethodB(context);
  return resultsA.Concat(resultsB).ToList();
}

更好的是,进行重组MethodAMethodB以便只向数据库发送一个查询。


推荐阅读