90

This is my code:

var banner = context.Banners.ToListAsync()
var newsGroup = context.NewsGroups.ToListAsync()
await Task.WhenAll(banner, newsGroup);

But when i called the function from controller. It showed error

A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

Please help me solve this issue.

1
  • I have 2 task. If i run each task. it's success. but if i run like my code above. It's error Commented Dec 17, 2013 at 8:16

3 Answers 3

122

The exception explains clearly that there is only one asynchronous operation per context allowed at a time.

So, you either have to await them one at a time as the error message suggests:

var banner = await context.Banners.ToListAsync();
var newsGroup = await context.NewsGroups.ToListAsync();

Or you can use multiple contexts:

var banner = context1.Banners.ToListAsync();
var newsGroup = context2.NewsGroups.ToListAsync();
await Task.WhenAll(banner, newsGroup);
Sign up to request clarification or add additional context in comments.

22 Comments

just a note, if you have a Lazy variable that uses the context in the query even with the await it will throw the same error, just get the property before the query, it was a pain to find out this.
@Pedro.The.Kid: As a general rule, don't use lazy loading with asynchronous DB access. Lazy loading is always synchronous, so it's far better to use Include or separate queries for the additional data.
Is there any specific reason why you need a context per async query? I feel like this becomes quite a bit of a limiting factor.
@Zapnologica: It's just the way ES6 was designed. Each context can only handle one query at a time. So if you finish one query before the next one begins, you'd only need one context. It's only a problem if you want to do multiple queries at the same time.
@StephenCleary, I am having a hard time finding that query as I there isn't anything immediately before the exception. Is there a way for us to find what is currently being executed? Thanks
|
4

If you are using IoC container for your Data Provider injection, consider to use "transient" or "PerWebRequest" type for your lifecycle.

For example: https://github.com/castleproject/Windsor/blob/master/docs/lifestyles.md

Comments

3

If you use Unity for dependency injection with for example repository pattern you will get the following error using two or more contexts with create/update/delete:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

This can be solved using PerRequestLifetimeManager. More info here:

C# EF6 make multiple async calls to one context using Unity - Asp.Net Web Api

container.RegisterType<DbContext>(new PerRequestLifetimeManager());
container.RegisterType<ISupplierRepository, SupplierRepository>();
container.RegisterType<IContactRepository, ContactRepository>();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.