2014-07-02 36 views
7

以下代碼將永久凍結。Task.Delay永不完成

public async Task DoSomethingAsync() 
{ 
    await Task.Delay(2000); 
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    DoSomethingAsync().Wait(); 
    // Task.Delay(2000).Wait(); 
} 

如果我切換調用DoSomethingAsync與註釋掉的代碼,其行爲與預期相同。我懷疑,不知何故,嵌套的等待正在導致死鎖,但我不知道爲什麼,或者如何解決它。

+0

可能重複的[異步/等待例子導致死鎖(http://stackoverflow.com/questions/15021304/an-async-await-example-that-c​​auses-a -deadlock) –

回答

22

假設Button_ClickGUI線程中運行,您的手中有一個死鎖。

當你,直到任務結束你同步阻塞線程任務使用Wait,但該任務永遠不會結束,因爲延續(的Task.Delay(2000);完成)必須在GUI線程上運行,以及(被屏蔽的Wait).

您有幾種解決方案,要麼使用ConfigureAwait(false)不捕捉GUI線程的SynchronizationContext:

public async Task DoSomethingAsync() 
{ 
    await Task.Delay(2000).ConfigureAwait(false); 
} 

或(我建議)使用async void事件處理(這是唯一合適的地方的async void法):的

private async void Button_Click(object sender, RoutedEventArgs e) 
{ 
    await DoSomethingAsync(); 
} 

public async Task DoSomethingAsync() 
{ 
    await Task.Delay(2000); 
} 
+1

花了我近3個小時找到一個gui-thread-async-await錯誤的原因......如果可以的話,我會給你兩個ups! –