What do you think will happen when you run these 2 snippets of code? They both looks quite similar at the first sight, don’t they.
This one
var results = new List<SomeClass>(); mylist.ForEach(async item => { var result = await SomeDbQueryAsync(item); results.Add(result); });
versus this one
var results = new List<SomeClass>(); foreach(var item in mylist) { var result = await SomeDbQueryAsync(item); results.Add(result); });
The code looks remarkably similar, but the 1st sample will throw this exception “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”
The reason is that the first approach should be used only for event handlers and never for DB query. As explained in this Stackoverflow answer. The first approach will start several asynchronous operations (one for each item in the list) and never wait for them to finish. (They will finish eventually, but the caller does not care).
There is but 1 case when the first approach will actually work. Switch to debug mode and insert a breakpoint somewhere inside the SomeDbQueryAsync() method. I am writing that because it bite me too 🙂
Happy coding!