2013-04-12 30 views
0

誰能教我,爲什麼在完成後的λ以下凍結:如預期Task.Run凍結

 return await Task.Run(() => 
     { 
      return SuperLongMethod(); 
     }) 

...但以下幾項工作:

 return Task.Run(() => 
     { 
      return SuperLongMethod(); 
     }).GetAwaiter().GetResult(); 

看來Task.Run在第一個版本中並不認識到lambda已經完成。我在我的代碼中還有其他例子,我使用第一個版本時沒有問題,所以我不知道它們有什麼不同。

爲了清楚起見,SuperLongMethod()使Web服務調用,並做了很多結果數據

回答

6

我猜測,進一步的處理後的你的調用堆棧你打電話Task.WaitTask<T>.Result,因此導致the deadlock issue I describe on my blog。您應該使用await

作爲一個側面說明,SuperLongMethod或許應該被分解成CallWebServiceAsyncDoPostProcessing,只有DoPostProcessing應該被包裹在一個Task.Run

+0

你的博客基本上說,遠離等待任務,這是解決這個混淆的僵局,但我使用Task.Run的原因是有效地強制處理到另一個線程,所以GUI保持流暢。否則,它會在後期處理過程中受到打擊。但是,您的博客建議在Task.Run上使用ConfigureAwait(false)完美工作:) – Sean

+0

我還應該補充一點,我的第二個示例代碼塊實際上是阻塞的,所以它不是'我認爲它是 – Sean

+2

解決方法其實,我的博客文章建議等待任務;它阻止任務中的*阻塞*。 「ConfigureAwait」工作的事實告訴我,你的代碼仍然不正確 - 進一步調用堆棧,你仍然阻塞從'async'方法返回的任務。 –