バックグラウンドスレッドで実行するタスクをトリガーしたい。タスクの完了を待ちたくありません。
.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を使用してタスクを実行して忘れる別の方法はありますか?