can not await async lambda

C#Task Parallel-LibraryAsync AwaitAsync Ctp

C# Problem Overview


Consider this,

Task task = new Task (async () =>{
    await TaskEx.Delay(1000);
});
task.Start();
task.Wait(); 

The call task.Wait() does not wait for the task completion and the next line is executed immediately, but if I wrap the async lambda expression into a method call, the code works as expected.

private static async Task AwaitableMethod()
{
    await TaskEx.Delay(1000);    
}

then (updated according comment from svick)

await AwaitableMethod(); 

C# Solutions


Solution 1 - C#

In your lambda example, when you call task.Wait(), you are waiting on the new Task that you constructed, not the delay Task that it returns. To get your desired delay, you would need to also wait on the resulting Task:

Task<Task> task = new Task<Task>(async () => {
    await Task.Delay(1000);
});
task.Start();
task.Wait(); 
task.Result.Wait();

You could avoid constructing a new Task, and just have one Task to deal with instead of two:

Func<Task> task = async () => {
    await TaskEx.Delay(1000);
};
task().Wait();

Solution 2 - C#

You need to use TaskEx.RunEx.

It natively supports running async methods on the TaskPool by awaiting the inner task internally. Otherwise you'll run into the issue you're facing, where only the outer task is awaited, which obviously completes immediately, leaving either a task which still needs awaiting, or in your case (and even worse) a void lambda which cannot be awaited.

Alternatively, you can await the task twice, providing you construct your outer task correctly (which currently you are not).

Current code (fixed):

Task task = new Task<Task>(async () =>{
    await TaskEx.Delay(1000);
});

task.Start();
var innerTask = await task;
await innerTask;

Using TaskEx.RunEx:

Task task = TaskEx.RunEx(async () =>{ // Framework awaits your lambda internally.
    await TaskEx.Delay(1000);
});

await task;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkennyzxView Question on Stackoverflow
Solution 1 - C#Joe DaleyView Answer on Stackoverflow
Solution 2 - C#Lawrence WagerfieldView Answer on Stackoverflow