ファイア アンド フォーゲット タスクに Task オブジェクトを利用する場合、Dispose を呼び出す必要があるかという疑問が生じます。 ()?
バックグラウンド スレッドの実行とTask.Dispose()
タスク並列ライブラリ (TPL) を使用すると、バックグラウンド スレッドでタスクを実行できます。通常、StartNew() は IDisposable を実装する Task オブジェクトを作成するために使用されます。 MSDN ドキュメントによると、タスクへの最後の参照を解放する前に Dispose() を呼び出すことが推奨されています。
バックグラウンド タスクの破棄のジレンマ
ただし、Dispose() を呼び出すにはタスクを完了する必要がなく、バックグラウンド スレッドを使用する目的が無効になります。さらに、クリーンアップに使用できる完了イベントはありません。
Is It Acceptable to Not Dispose()?
Microsoft の Stephen Toub によると、ほとんどの場合、 、内部待機ハンドルが割り当てられないため、継続に使用される Task オブジェクトに対して Dispose() を呼び出さなくても問題ありません。 .Net 4.5 では、AsyncWaitHandle を明示的に使用した場合のみ待機ハンドルが割り当てられます。
結果とリスク
Toub は、Task オブジェクト自体にはファイナライザーがないことに注意してください。 。待機ハンドルにはファイナライザーがありますが、必要な場合にのみ割り当てられます。したがって、待機ハンドルが割り当てられない限り、ファイナライザーは実行されません。
ただし、多数のファイア アンド フォーゲット タスクが作成される場合、複数のタスクが存在すると、ファイナライザー スレッドが過負荷になる可能性があります。待機ハンドルが割り当てられます。
ドキュメントとベスト プラクティス
タスク クラスの MSDN ページには割り当てられていません。この問題に明示的に対処します。ただし、「タスクを破棄する必要がありますか?」というタイトルの Stephen Toub のブログ投稿では、さらに明確な説明が提供され、ほとんどの場合はファイナライズに依存することが推奨されています。
代替アプローチ
必要に応じて、待機ハンドルが利用可能かどうかを確認し、割り当てられている場合はタスクを破棄する方法があります。あるいは、ThreadPool.QueueUserWorkItem メソッドや Reactive Extensions for .NET (Rx) の使用など、ファイア アンド フォーゲット タスクの他のオプションを検討することもできます。
以上がFire-and-Forget TPL タスクを Dispose() する必要がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。