Reputation: 2484
I have a list of async functions I want to execute in order. When I run the following code I get the output:
Task 1 before
Task 2 before
Finished tasks
Why are my async functions not being awaited correctly?
[Test]
public async Task AsyncTaskList()
{
var data = "I'm data";
var tasks = new List<Func<object, Task>>() {Task1, Task2};
tasks.ForEach(async task =>
{
await task(data);
});
Debug.WriteLine("Finished tasks");
}
private static async Task Task1(object data)
{
Debug.WriteLine("Task 1 before");
await Task.Delay(1000);
Debug.WriteLine("Task 1 after");
}
private static async Task Task2(object data)
{
Debug.WriteLine("Task 2 before");
await Task.Delay(1000);
Debug.WriteLine("Task 2 after");
}
Upvotes: 0
Views: 1438
Reputation: 9587
Because the await
inside your ForEach
delegate actually completes after the method exits. Change it to an actual foreach
loop and awaiting will work as expected.
ForEach
has no specific handling for Func<Task>
(few delegate-accepting methods in the Base Class Library do, and you should note that they will almost invariably return a Task
themselves). ForEach
will only run the synchronous portion of your lambda - and that is the portion preceding the first await
of a Task
which does not complete synchronously (which is Task.Delay
in your case). This is why you're seeing the "before" messages popping up at the expected time. As soon as your delegate hits await Task.Delay
, the the rest of your lambda is scheduled to run sometime in the future and ForEach
moves on to the next item in the list. The scheduled task continuations will then run unobserved and complete later.
Upvotes: 4