我偶然发现了async-await的奇怪行为。
示例代码:
public class foo
{
public async static Task<myobj> method1()
{
var result = await method2();
return result;
}
private async static Task<myobj> method2()
{
// omitted for brevity.
}
}
public class bar
{
public void caller()
{
var result = foo.method1().Result;
pass(result);
}
}
这会冻结用户界面。解决方案是在caller()上实现async-await。
但是这个怎么样:
public class foo
{
public static myobj method1()
{
var result = method2().Result;
return result;
}
private async static Task<myobj> method2()
{
// omitted for brevity.
}
}
public class bar
{
public void caller()
{
var result = foo.method1();
pass(result);
}
}
这是免费的。
私人电话与其他班级的上游方法有什么不同?
答案 0 :(得分:4)
正如我在评论中提到的,第一种情况是described in great details by Stephen Cleary in his blog。
死锁发生在await method2()
。 await
延续通过SynchronizationContext.Post
发布到UI线程的同步上下文。但UI线程已在此行等待阻止:foo.method1().Result
。消息泵被阻塞,持续回调永远不会被泵入和调用,死锁。
在第二种情况下,我在任何地方都看不到await
。即,您显示的代码不会发生任何异步。我猜这就是它的原因。