當使用 Task 物件進行即發即棄任務時,出現了問題:是否有必要呼叫 Dispose ()?
後台執行緒執行和Task.Dispose()
任務並行庫 (TPL) 允許在後台執行緒上執行任務。通常,StartNew() 用於建立一個實作 IDisposable 的 Task 物件。根據 MSDN 文檔,建議在釋放對任務的最後一個引用之前調用 Dispose()。
處理後台任務的困境
但是,呼叫 Dispose() 需要要完成的任務,這違背了使用後台執行緒的目的。此外,沒有可用於清理的完成事件。
不 Dispose() 可以接受嗎?
根據 Microsoft 的 Stephen Toub 的說法,在大多數情況下,可以不對用於延續的 Task 物件呼叫 Dispose(),因為它們不會分配內部等待句柄。從 .Net 4.5 開始,只有明確使用 AsyncWaitHandle 才會導致等待句柄分配。
後果與風險
Toub 指出 Task 物件本身沒有終結器。等待句柄有一個終結器,但僅在必要時才分配。因此,除非分配等待句柄,否則終結器不會執行。
但是,在建立許多即發即棄任務的情況下,如果多個任務,則終結器執行緒可能會被淹沒。等待句柄已分配。
文件和最佳實踐
MSDN 頁面任務類別沒有明確解決這個問題。然而,Stephen Toub 的部落格文章,標題為「我需要處置任務嗎?」提供了進一步的說明,並建議在大多數情況下依靠最終確定。
替代方法
如果需要,可以透過多種方法檢查等待句柄的可用性,並在已分配任務時將其處置。或者,人們可以探索「即發即忘」任務的其他選項,例如 ThreadPool.QueueUserWorkItem 方法或使用 .NET 的響應式擴充 (Rx)。
以上是我應該 Dispose() 一次性 TPL 任務嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!