Michael Sagalovich
Michael Sagalovich

Reputation: 2549

Task.WaitAll hangs with async/await tasks

I must be missing something obvious, like a deadlock on SynchronizationContext, but I do not see why it happens, and do not understand how I can avoid it...

So, the application is Azure WorkerRole (essentially, as far as I understand, usual Windows app without UI). In the application, I am trying to parallel execution of a number of tasks, and the schematic version of my code is this:

private async Task DoJob()
{
    await SomeIoOperation();
}


public void MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
    Log("Start");
    Task.WaitAll(DoJob(), DoJob(), DoJob());
    Log("End");
}

My idea here is that we are operating with default SynchronizationContext here, so we should avoid the deadlock that we would have in similar situation in, for example, ASP.NET.

However, sometimes execution hangs - Start is logged, End is not for days until I restart the worker role. Naturally,there is no way DoJob could be running that long. Oddly, this does not happen immediately after the worker role starts - it may take days or weeks of normal operation until it hangs.

I could be simplifying the code too much - maybe it is important what exactly happens in SomeIoOperation - but I feel this is something obvious related to SynchronizationContext misuse.

Will SomeIoOperation.ConfigureAwait(false) help? I cannot even test it, because I do not know if it is working because the issue is fixed, or will eventually hang after a few more days.

Ideas?

Upvotes: 7

Views: 5281

Answers (1)

Kirill Bestemyanov
Kirill Bestemyanov

Reputation: 11964

You exactly fall in deadlock on SynchronizationContext. Just use WhenAll instead of WaitAll:

public async Task MethodExecutedByWorkerRoleInAnInfiniteLoop()
{
    Log("Start");
    await Task.WhenAll(DoJob(), DoJob(), DoJob());
    Log("End");
}

and all will work.

Upvotes: 14

Related Questions