私たちは最近、重いバックグラウンド タスクを実行するためのツールキットとして TPL を採用しました。
これらのタスクは通常、 を実装する単一のオブジェクトを生成します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
で呼び出しRunOnUiThread
て、その結果を UI スレッドに渡します。タスクt
は UI スレッドでスケジュールされ、data
渡されたものの所有権を取得しt
ます。UI スレッドのメッセージ ポンプがシャットダウンされたために実行できなかった場合、継続が実行されると予想していましたが、タスクに失敗し、自分でオブジェクトを破棄します。DisposeObject()
オブジェクトを破棄する前に、オブジェクトが実際に IDisposable であり、null でないかどうかをチェックするヘルパーです。
残念ながら、うまくいきません。バックグラウンド タスクのt
作成後にアプリケーションを閉じると、継続が実行されません。
以前にこの問題を解決しました。当時、私は Threadpool と WPF Dispatcher を使用して UI スレッドにメッセージを投稿していました。あまりきれいではありませんでしたが、最終的にはうまくいきました。このシナリオでは TPL の方が優れていることを期待していました。IDisposable を実装している場合は、残りの AsyncState オブジェクトをすべて破棄する必要があることを TPL に教えることができれば、さらに良いでしょう。
したがって、コードは主に問題を説明するためのものです。Disposable オブジェクトをバックグラウンド タスクから UI スレッドに安全に引き渡すことができるソリューション、できればコードをできるだけ少なくするソリューションについて学びたいと考えています。