ASP.NET Core Task.WhenAll - A second operation started on this context before a previous operation completed

Viewed 818

I started trying to convert my db queries to be async, but I really don't understand how to do it correctly.

I am now getting the error:

A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with 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();
    
}

index.cs:

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

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

}

Index.cshml


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

I tired making the dbcontext transient, but it made no difference. I am also worried it will break a lot of my other code which updates entries in the db.

I can see why the error is happening, I am running two queries on the same context, but I don't know how to fix it.

Can anyone advise?

1 Answers

I can see why the error is happening, I am running two queries on the same context, but I don't know how to fix it.

The easiest way to fix it is to only run one query at a time:

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

Even better, restructure MethodA and MethodB so that only one query is sent to the database.

Related