まず、私がやろうとしていることを説明します。
コンポーネント Bを使用しているコンポーネント Aがあります。
両者の間で通信するには、イベントを使用する必要があります。
ここでの前提条件の 1 つは、コンポーネント Bを非同期で実行し、イベント ハンドラーを呼び出された順序で実行することです。
また、呼び出しのパイプをキャンセルしたい(ユーザーが要求した場合)。したがって、まだ実行されていない、呼び出されたすべてのイベント ハンドラは実行されません。
達成するためのソリューションは TPL です。私がやろうとしていることのPOCを作成しました:
static void Main(string[] args)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var t = Task.Factory.StartNew(() => DoSomeWork(token));
//.ContinueWith((prevTask) => DoSomeWork(token));
t.ContinueWith((prevTask) => DoSomeWork(token));
Task.WaitAll(t);
Console.WriteLine("Finish");
Console.ReadKey();
}
static int id = 1;
static void DoSomeWork(CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(1000);
Console.WriteLine(id++);
}
このスニペットの出力があります:
1
終了
2
ご覧のとおり、実際に終了する前に終了します。Finishの後に2が表示されます。
これで前のコードを変更すると、動作します:
static void Main(string[] args)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var t = Task.Factory.StartNew(() => DoSomeWork(token))
.ContinueWith((prevTask) => DoSomeWork(token));
//t.ContinueWith((prevTask) => DoSomeWork(token));
Task.WaitAll(t);
Console.WriteLine("Finish");
Console.ReadKey();
}
static int id = 1;
static void DoSomeWork(CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(1000);
Console.WriteLine(id++);
}
このスニペットの出力があります:
1
2
終了
ご存じのように、タスク宣言で continueWith ステートメントを使用する必要はありませんが、イベントが発生したときに使用します。
なぜ Task.WaitAll(t); 最初のサンプルで動作しませんか?
誰でも私を助けることができますか?