2番目のコードブロックでアクションブロックの完了を待っているときに、最初のコードブロックがなぜスローされるのか説明できますか?データフローブロックの連鎖はないので、伝播は必要ありません。Actionブロックの例外処理を理解する
ActionBlock定義1:
ActionBlock<int> workerBlock = new ActionBlock<int>(async (i) =>
{
await Task.Delay(1);
throw new OperationCanceledException();
});
ActionBlock定義2:
ActionBlock<int> workerBlock = new ActionBlock<int>(async (i) =>
{
await ExceptionThrower1();
});
private static async Task ExceptionThrower1()
{
CancellationTokenSource source= new CancellationTokenSource();
source.CancelAfter(100);
await ExceptionThrower2(source.Token);
}
private static async Task ExceptionThrower2(CancellationToken token)
{
await Task.Delay(1000);
try
{
token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException e)
{
Console.WriteLine(e);
throw;
}
}
テストプログラム:私は最初の定義を使用する場合は、 "完了"
workerBlock.SendAsync(1).GetAwaiter().GetResult();
workerBlock.SendAsync(1).GetAwaiter().GetResult();
workerBlock.SendAsync(1).GetAwaiter().GetResult();
workerBlock.Complete();
workerBlock.Completion.GetAwaiter().GetResult();
Console.WriteLine("Done");
取得していません完了を待って例外がスローされるため、印刷されます。 2番目の定義では、「完了」が表示されますが、ExceptionThrower2で例外が表示されていることがわかります。
このblogpostに基づいて - https://blogs.msdn.microsoft.com/pfxteam/2011/11/09/exception-handling-in-tpl-dataflow-networks/でも、2番目のものは考慮され、処理されない例外であり、完了時にスローされるべきですか?
ええ、そうです。私はこの間、最初のスニペットでちょうど "例外"を使用しようとしていたと思います。 OperationCanceledExceptionは、別の方法で扱われます。 – RLV