最近、重いバックグラウンドタスクを実行するためのツールキットとしてTPLを採用しました。TPLでUIスレッドに `Disposable`オブジェクトを安全に渡す
これらのタスクは、通常、IDisposable
を実装する単一のオブジェクトを生成します。これは内部的にいくつかのOSハンドルがあるためです。
バックグラウンドスレッドによって生成されたオブジェクトは、ハンドオーバがアプリケーションシャットダウンと同時に発生した場合でも、常に適切に処理されます。
がprivate void RunOnUiThread(Object data, Action<Object> action)
{
var t = Task.Factory.StartNew(action, data, CancellationToken.None, TaskCreationOptions.None, _uiThreadScheduler);
t.ContinueWith(delegate(Task task)
{
if (!task.IsCompleted)
{
DisposableObject.DisposeObject(task.AsyncState);
}
});
}
背景がTask
UIスレッドにその結果を渡すためにRunOnUiThread
を呼び出します。
t
タスクはUIスレッドでスケジュールされ、
data
の所有権が渡されます。
t
が実行できなかった場合、uiスレッドのメッセージポンプがシャットダウンされたため継続が実行され、タスクは失敗し、オブジェクトを自分で処分しました。
DisposeObject()
は、オブジェクトが実際にIDisposableで、nullでない場合、それを廃棄する前にチェックするヘルパーです。
悲しいことに、うまくいきません。バックグラウンドタスクt
の作成後にアプリケーションを閉じると、継続は実行されません。
私は以前この問題を解決しました。当時、私はスレッドスレッドとWPFディスパッチャーを使ってメッセージをUIスレッドに投稿していました。それはあまりにもかわいいものではありませんでしたが、結局はそれは働きました私はTPLがこのシナリオでより良いと思っていました。 IDisposableを実装している場合は、残っているAsyncStateオブジェクトをすべて破棄する必要があることをTPLに教えることができればさらに良いでしょう。
したがって、コードは主に問題を説明することです。私は、バックグラウンドタスクから使い捨てオブジェクトをUIスレッドに安全にハンドオーバできる任意のソリューションについて学びたいと思います。できるだけコードを少なくすることをお勧めします。
あり、単に何のポイントを。オブジェクトが必要以上に長くならないようにオブジェクトを破棄します。プロセスのシャットダウン後も何も残っていません。 Windowsは開いたままのハンドルをクリーンアップします。 AppDomainは、それ自体は必要ないでしょうが、シャットダウンする前にファイナライザを実行します。未完成のタスクがまだ残っている間にアプリをシャットダウンできるようにするのが良い方法があります。 –