あなたの答えはコールバックだと思います。
長期実行スレッドを設定する場合は、メソッドへの参照を渡します。コールバックメソッドをタスクメソッドに渡すか、デリゲートのBeginInvoke()機能に組み込まれているAsyncCallbackデリゲートインスタンスを設定することができます。あなたのコールバックメソッドがたIAsyncResultを受け入れ、特定のデリゲートの定義に準拠する必要があり、
public void StartMyTwoTasks()
{
//I'm passing the callback to the task method directly; you may prefer to pass it to BeginInvoke()
var task1Lambda =()=>Task1(TaskCompleted);
var task2Lambda =()=>Task2(TaskCompleted);
task1Lambda.BeginInvoke(null,null);
task2Lambda.BeginInvoke(null,null);
}
public void Task1(Action<int> task1Complete)
{
//perform your long-running calculation or data retrieval/transformation here
Thread.Sleep(10000);
//when finished, call the callback method.
//You may need to use Control.Invoke() to make sure the callback is executed on the UI thread
//If you use the AsyncCallback feature of BeginInvoke/EndInvoke, you don't have to make the call here.
taskComplete(1);
}
public void Task2(Action<int> taskComplete)
{
//Ditto
Thread.Sleep(8000);
taskComplete(2);
}
public void Task1Complete(int taskNumber)
{
TasksComplete[taskNumber-1] = true;
If(TasksComplete.All(x=>x==true))
DoSomethingOnceAllTasksAreComplete();
}
AsyncCallback機能を使用していますが、中に適切にそれを呼び出すことを心配する必要はありません。ここで
は、基本的な例ですあなたの方法;フレームワークはあなたのコールバックを処理します:
public public void StartALongTask()
{
var taskLambda =()=>PerformTask();
taskLambda.BeginInvoke(TaskComplete,null);
}
//one advantage is that you can call a method that returns a value very easily.
public IEnumerable<string> PerformTask()
{
//long-running task
Thread.Sleep(5000);
return Enumerable.Repeat("result", 100);
//look ma, no callback invocation.
//This makes asynchronous delegates very useful for refactoring a synchronous
//operation without a lot of code changes.
}
//Here's the callback, which is invoked properly by the runtime when the thread is complete
public void TaskComplete(IASyncResult ar)
{
//calling EndInvoke on the same delegate, which is available in the AsyncResult,
//returns the return value of that delegate as if you'd called it synchronously.
var results = ar.AsyncDelegate.EndInvoke(ar);
//Now you can do something with those results.
}
これらのモデルはいずれもうまく機能します。他のオプションには、イベントの設定が含まれます。イベントは、完了すると各メソッドによって発生します。イベントは実際にはいくつかのシンタックスシュガーを持つ "マルチキャスト"デリゲートなので、ほぼ同じように動作します。
これは私が探しているものです。私はフレームワークにこのようなものがあると思っていましたが、私はそれを見つけることができませんでした。 – Mas