バックグラウンド スレッドで実行するタスクをトリガーしたいと考えています。タスクの完了を待ちたくありません。
.net 3.5 では、次のようにしました。
ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
.net 4 では、TPL が推奨される方法です。私が推奨する一般的なパターンは次のとおりです。
Task.Factory.StartNew(() => { DoSomething(); });
ただし、StartNew()
メソッドはTask
を実装するオブジェクトを返しますIDisposable
。これは、このパターンを推奨する人々によって見落とされているようです。Task.Dispose()
メソッドに関するMSDNのドキュメントには、次のように記載されています。
「タスクへの最後の参照を解放する前に、必ず Dispose を呼び出してください。」
タスクが完了するまで dispose を呼び出すことはできないため、メイン スレッドを待機させて dispose を呼び出すと、そもそもバックグラウンド スレッドで実行する意味がなくなります。また、クリーンアップに使用できる完了/終了イベントもないようです。
Task クラスの MSDN ページはこれについてコメントしておらず、本「Pro C#2010...」は同じパターンを推奨しており、タスクの破棄についてはコメントしていません。
そのままにしておくと、最終的にファイナライザーがそれをキャッチすることはわかっていますが、このような多くのファイアアンドフォーゲットタスクを実行していて、ファイナライザースレッドが圧倒されたときに、これが戻ってきて噛むことはありますか?
だから私の質問は:
Dispose()
この場合、Task
クラスを呼び出さないことは許容されますか? もしそうなら、なぜ、そしてリスク/結果がありますか?- これについて説明しているドキュメントはありますか?
Task
または、私が見逃したオブジェクトを処分する適切な方法はありますか?- または、TPL を使用してファイア アンド フォーゲット タスクを実行する別の方法はありますか?