2015-10-19 78 views
-1

有人可以解釋爲什麼AsyncMethod2會導致死鎖?我(想我)明白AsyncMethod1中的頂級任務不會嘗試在BlockingMethod捕獲的上下文中執行它的延續,因此可以避免死鎖,但我不明白AsyncMethod2引擎蓋下發生了什麼:如果ConfigureAwait(false)在迭代中,那麼爲什麼不防止死鎖?

private static void BlockingMethod(IEnumerable<Object> data) 
{ 
    AsyncMethod1(data).Wait(); // no deadlock 
    AsyncMethod2(data).Wait(); // deadlock 
} 

private static async Task AsyncMethod1(IEnumerable<Object> data) 
{ 
    await Task.Run(async() => 
    { 
     foreach (var obj in data) 
     { 
      await AsyncMethod2.(obj); 
     } 
    }).ConfigureAwait(false); 
} 

private static async Task AsyncMethod2(IEnumerable<Object> data) 
{ 
    await Task.Run(async() => 
    { 
     foreach (var obj in data) 
     { 
      await AsyncMethod2.(obj).ConfigureAwait(false); 
     } 
    }); 
} 

回答

4

AsyncMethod2await正在迴歸它的上下文。我指的是await,實際上是AsyncMethod2 - 即await Task.Run(...);。對於await,沒有ConfigureAwait(false),因此它將恢復到其上下文。

循環中是否存在ConfigureAwait(false)並不重要,因爲該循環運行在沒有上下文的線程池線程(Task.Run)上。

+0

非常感謝:)我想確保我得到它 - 當await Task.Run(...)返回到它的上下文時,會發生死鎖,對嗎?因爲該上下文被'BlockingMethod(...)'捕獲。那是對的嗎? –

+0

@shay__:上下文由'AsyncMethod2'捕獲。更確切地說,它被'await Task.Run(...)'語句捕獲。請記住,'await Task.Run(...);'與var runTask = Task.Run(...)基本相同; await runTask;'並且在'await runTask;'之前立即捕獲上下文,並且用於在'await runTask;'之後立即恢復該方法。 –

+0

所以現在我更加困惑,哈哈。 '等待Task.Run(...)'捕獲上下文 - 誰是第二個嘗試恢復到上下文的任務? –

相關問題