Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 769
Michael Sagalovich Avatar asked Oct 15 '15 06:10

Michael Sagalovich


1 Answers

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.

like image 58
Kirill Bestemyanov Avatar answered Oct 16 '22 13:10

Kirill Bestemyanov