2014-03-26 440 views
2

我偶然發現了異步等待的奇怪行爲。異步等待的異步行爲

示例代碼:

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); 
    } 
} 

這凍結UI。解決方案是在caller()上實現異步等待。

但是這個怎麼樣:

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); 
    } 
} 

這種自由的工作。

私人電話與其他類別的上行方法有什麼不同?

+2

確切的情況在這裏描述:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – Noseratio

回答

4

正如我在評論中提到的,第一種情況是described in great details by Stephen Cleary in his blog

該死鎖發生在await method2()await延續通過SynchronizationContext.Post發佈到UI線程的同步上下文。但是UI線程已經被阻塞在這條線上:foo.method1().Result。消息泵被阻塞,並且繼續回調從不被泵送和調用,造成死鎖。

在第二種情況下,我沒有在任何地方看到await。也就是說,你所顯示的代碼不會有任何異步。我想這就是它工作的原因。