异步等待的异常行为

时间:2014-03-26 08:27:30

标签: c# asynchronous async-await

我偶然发现了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);
    }
}

这是免费的。

私人电话与其他班级的上游方法有什么不同?

1 个答案:

答案 0 :(得分:4)

正如我在评论中提到的,第一种情况是described in great details by Stephen Cleary in his blog

死锁发生在await method2()await延续通过SynchronizationContext.Post发布到UI线程的同步上下文。但UI线程已在此行等待阻止:foo.method1().Result。消息泵被阻塞,持续回调永远不会被泵入和调用,死锁。

在第二种情况下,我在任何地方都看不到await。即,您显示的代码不会发生任何异步。我猜这就是它的原因。