2013-01-06 49 views
1

我有以下的擴展方法:C#.NET 4.5的異步等待Task.Wait()阻塞問題

internal static string ReadLine(this DataReader stream) 
{ 
    Task<string> line = ReadLineAsync(stream); 
    // line.Wait(); - Not Required, as next call blocks 
    return line.Result; 
} 

它基本上是返回一個字符串的異步方法調用同步方法調用包裝。如果我一行一行地執行代碼,代碼工作正常,但是如果我讓它自由執行,我會遇到一個無限期的代碼塊。有任何想法嗎?

相關上一個問題我貼:How can I update my API to use the async keyword without using await for all callers

+2

你究竟得到了什麼?順便說一句,你不需要呼叫line.Wait,呼叫line.Result是一個阻止呼叫,如果結果不可用 – MBen

+0

我改變了我的方法考慮到你的意見。該應用程序只是掛起,我沒有看到我的輸出或VS 2012中的本地窗口中的任何東西。 – c0D3l0g1c

+0

你是從UI線程運行這個嗎? – dtb

回答

8

正如一些評論回答您的其他問題,如果你在一個GUI應用程序中使用Task.Result,你可能cause a deadlock(正如我在細節上我的博客解釋) 。

簡而言之:

  • 你開始在UI線程異步操作。請注意,任務line代表ReadLineAsync方法,並在該方法完成時完成。
  • ReadLineAsync調用await對某些不完整的操作。這導致ReadLineAsync返回一個不完整的任務(line)。
  • 您將阻止等待line的UI線程完成。
  • await ed操作完成時,它會將ReadLineAsync的其餘部分安排到UI線程。
  • UI線程無法完成ReadLineAsync,因爲它被同步阻塞,等待ReadLineAsync完成。僵局。

請參閱my answer to your other question解決此問題的方法。總之:

  • 無處不在使用ConfigureAwait(false)
  • 將錯誤處理更改爲Result將錯誤包裝在AggregateException中。
-2

據:http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx 你不是應該做的:

internal static string ReadLine(this DataReader stream) 
{ 
    string line = await ReadLineAsync(stream); 
    return line 
} 

這麼說,我還沒有開始這個異步業務。但是我讀過文件等等。

+0

你不能在非'async'方法內使用'await' – W0lfw00ds

+0

是的 - 我現在知道了。我是一個noob然後:( –