我有以下方法:
public override bool SyncNavigationMethod()
{
AsyncShowDialog().Wait();
return true;
}
public Task AsyncShowDialog()
{
//code to show dialog and process user input from the dialog.
}
当调用SyncNavigationMethod时,应用程序会陷入死锁状态。
我的猜测是它在等待AsyncShowDialog完成的MainThread上运行,并且显示的对话框无法调用它的回调,因为它是调用它的MainThread。因此,主线程等待自己,这是一个僵局。
更多信息:
我是否正确怀疑死锁?
如何在没有此死锁的情况下从SyncNavigationMethod调用AsyncShowDialog?
感谢。
答案 0 :(得分:2)
我将从 Stephen Cleary 的最佳博客post开始,它解释了异步调用的同步阻塞如何导致死锁,这是真的除Console之外的所有系统,它没有UI上下文线程:
现在关于你的代码和要点:
所以,主线程等待自己,这是一个僵局。
是的,你已经正确地理解它是一个死锁,因为Mainthread阻塞了自己
Wait, Result and ManualResetEvent
,它们都同步阻止异步代码,因此结果相同
可能的解决方案:
如果通话是Rest API
或web based call
,那么请将所有内容Async
和IIS确保它可以返回后级Async-Await
执行,类似于:
public async override Task<bool> SyncNavigationMethod()
{
await AsyncShowDialog();
return true;
}
public async Task AsyncShowDialog()
{
await SomeOperation();
}
Task<bool>
的返回值将自动解包
其他选择:
如果您无法制作SyncNavigationMethod() Async
,请尝试以下操作:
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();
}