This helps to think of await as a suspension of the current method, although it does not block the thread.
In the first example, when you execute the foreach , every time you create a Processor , start the operation (keeping the Task operation in the list) and then delete the Processor . After the foreach completes, you (asynchronously) wait for all operations to complete.
In the second example, when you execute the foreach , every time you create a Processor , start the operation (asynchronously), wait for it to complete, and then delete the Processor .
To fix this, you should write a helper method, as such:
private static async Task ProcessData(int data) { using (var processor = new Processor(d)) { processor.Completed += (sender, e) => { }; await processor.ProcessAsync(); } }
Your helper method defines a higher-level operation that takes care of disposing of Processor own resource at the appropriate time. Then you can simultaneously start all your work as follows:
public async Task ProcessData(IEnumerable<int> data) { ... await Task.WhenAll(data.Select(d => ProcessData(d))); ... }
source share