Reputation: 21
I have the following methods:
public override bool SyncNavigationMethod()
{
AsyncShowDialog().Wait();
return true;
}
public Task AsyncShowDialog()
{
//code to show dialog and process user input from the dialog.
}
what happens is that the app goes into a deadlock when SyncNavigationMethod is called.
My guess is that it runs on the MainThread, who is waiting for AsyncShowDialog to complete, and the dialog that is shown cannot call it's callback because it's the MainThread that calls it. And so, the main thread waits to itself and it's a deadlock.
More information:
Am I right suspecting a deadLock?
How can I call AsyncShowDialog from SyncNavigationMethod without this deadlock?
Thanks.
Upvotes: 1
Views: 538
Reputation: 11478
I will start with one of the best blog post by Stephen Cleary, which explains, how the synchronous blocking of an asynchronous call leads to deadlock and that's true for all systems except Console, which doesn't have a UI context thread:
Now regarding your code and points:
And so, the main thread waits to itself and it's a deadlock.
Yes it does, you have correctly understood it's a deadlock, due to Mainthread blocking itself
Wait, Result and ManualResetEvent
, they all synchronously block the Async code, thus the same result
Possible solution:
If the call is a Rest API
or a web based call
, then make the everything Async
and IIS will ensure that it can return post top level Async-Await
execution, something like:
public async override Task<bool> SyncNavigationMethod()
{
await AsyncShowDialog();
return true;
}
public async Task AsyncShowDialog()
{
await SomeOperation();
}
Return value of Task<bool>
would be automatically unwrapped
Other option:
If you cannot make the SyncNavigationMethod() Async
, then try this:
public override bool SyncNavigationMethod()
{
List<Task> taskList = new List<Task>();
taskList.Add(AsyncShowDialog());
Task.WhenAll(taskList.ToArray());
return true;
}
public async Task AsyncShowDialog()
{
await SomeOperation();
}
Upvotes: 2