2017-03-27 197 views
0

目前我進入異步/等待的關鍵字,並通過以下幾個問題去:When correctly use Task.Run and when just async-awaitAsync/Await vs Threads請等待後臺線程?

然而,即使第二個鏈接不回答我的問題,這是當簡單地使用

Task.Run(...) 

await Task.Run(...) 

它是情境或者是有通過使用的await(從而返回給調用)來獲得什麼?

+5

像任何其他使用任務一樣,不等待會導致任務被觸發並立即繼續執行當前方法,等待時將返回一個任務並將該方法的其餘部分連接爲一個延續(有效地停止執行直到任務完成)。你想達到什麼目的? –

+0

@AntP由於我對這些關鍵字不太熟悉,我只是想了解是否使用await創建後臺線程而不是直接觸發它們,或者如果使用await Task.Run(。 ..)更具情境性,那麼,我應該在什麼情況下做呢? – Iason

+0

這兩件事產生不同的行爲,所以它是情境 - 如果你想返回一個不完整的'任務',可以在堆棧上進一步等待(例如附加額外的延續,處理失敗......),你需要等待(或返回)由Task.Run返回的任務。如果你想解僱任務而忘了它,你不想等待它。 –

回答

4

代碼Task.Run(...)(在均爲示例)將委託發送到線程池並返回將包含該委託結果的任務。這些「結果」可以是實際的返回值,也可以是例外。您可以使用返回的任務來檢測結果何時可用(即代表何時完成)。

所以,你應該使用的Task如果以下任爲真:

  • 您需要在操作完成檢測並以某種方式作出迴應。
  • 您需要知道操作是否成功完成。
  • 您需要處理操作中的異常。
  • 你需要做一些操作的返回值。

如果你調用代碼需要做任何的那些,然後使用await

await Task.Run(...); 

具有長期運行的後臺任務,有時你想要做的那些(例如,檢測例外),但你不想做馬上;在這種情況下,只需保存Task然後await它在你的應用程序的一些其他問題:

this.myBackgroundTask = Task.Run(...); 

如果不需要上述的任何,那麼你可以做一個「射後不理」 ,因爲這樣的:

var _ = Task.Run(...); // or just "Task.Run(...);" 

需要注意的是真正的「射後不理」的應用是極爲罕見。這實際上是說「運行這個代碼,但我不在乎它是否完成,何時完成,或者它是否成功」。

1

當使用fire和forget類型處理邏輯時,您可以使用Task.Run(),類似於在某人訂閱它們時調用事件。您可以使用此日誌記錄,通知等

如果你依賴的結果,或在你的方法執行的操作,你需要使用等待Task.Run(),因爲它暫停當前執行,直到你的任務完成。