ドキュメント CancellationTokenSource.Cancel を読んだとき、例外をスローすることは想定されていません。
CancellationTokenSource.Cancel
cts.Cancel(); の呼び出しの下 OperationCanceledException を引き起こしている (スローしていない)。
その行をコメントアウトしたかのように、最後の OperationCanceledException がスローされないことを非常に確信しています。
cts.Cancel 行がアクティブな場合、例外をスローしている行は t2.Wait(token); です。
cts.Cancel(); に遅延がある場合 次に t2.Wait(トークン); 行が呼び出されるとすぐに例外をスローしません。
t2.Wait(トークン); cts.Cancel() が実行されたときにのみその例外をスローします。
それは適切な行動ですか?
一貫性がある場合は、それで問題ありませんが、cts.Cancel で例外が発生することは望ましくありません。
私は明らかに混乱しています。動作を理解したいだけなので、これを本番環境に快適に持ち込むことができます。
現在、BackGroundWorker を使用してこれを行っており、wait と cancel を使用して簡単に追跡および維持できると考えました。
if (token.IsCancellationRequested || ctr == 100000000)
まだ ctr == 100000000
でスローする
このコードに何か問題がありますか?
それとも、それがどのように機能するはずですか?
Task t2 = Task.Run に try catch がないと、キャッチされない例外がスローされました。
t2 の try catch でキャッチされると思っていましたが、一度に 1 つずつ質問してください。
これは .NET 4.5 のコンソール アプリです。
static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Task.Run(() =>
{
Thread.Sleep(1000);
cts.Cancel(); // this is thowing an exception that is caught on the last catch (OperationCanceledException Ex)
// according to the documentation this is not supposed
// if I comment out the cts.Cancel(); then the exeption is not thrown
if (token.IsCancellationRequested)
Console.WriteLine("Cancellation requested in Task {0}.",
Task.CurrentId);
else
Console.WriteLine("Cancellation Not requested in Task {0}.",
Task.CurrentId);
}, token);
//tried this but did not help
//Task.Run(() =>
//{
// //Thread.Sleep(1000);
// if (token.IsCancellationRequested)
// Console.WriteLine("Cancellation requested in Task {0}.",
// Task.CurrentId);
//}, token);
//Thread.Sleep(1000);
////cts.Cancel();
Task t2 = Task.Run(() =>
{
try
{
Console.WriteLine("Task t2 started Int32.MaxValue = " + Int32.MaxValue.ToString());
Thread.Sleep(4000);
for (int ctr = 0; ctr < Int32.MaxValue; ctr++)
{
if (ctr < 100 || ctr % 100000000 == 0)
{
Console.WriteLine(ctr.ToString());
}
if (token.IsCancellationRequested || ctr == 100000000) // || ctr == 100000000
{
Console.WriteLine("ThrowIfCancellationRequested in t2 Task {0}.",
Task.CurrentId);
throw new OperationCanceledException(token);
//token.ThrowIfCancellationRequested();
}
}
Console.WriteLine("Task {0} finished.",
Task.CurrentId);
}
catch (OperationCanceledException Ex)
{
//Console.WriteLine(Ex.ToString());
Console.WriteLine("OperationCanceledException in Task t2 {0}: The operation was cancelled.",
Task.CurrentId);
}
catch (Exception Ex)
{
Console.WriteLine("Task t2 = Task.Run Exception Ex" + Ex.Message);
}
});
try
{
Console.WriteLine("t2.Wait a");
t2.Wait(token);
}
catch (AggregateException e)
{
Console.WriteLine("AggregateException");
foreach (var v in e.InnerExceptions)
Console.WriteLine(e.Message + " " + v.Message);
}
catch (OperationCanceledException Ex)
{
//Console.WriteLine(Ex.ToString());
Console.WriteLine("OperationCanceledException in Task {0}: The operation was cancelled.",
t2.Id);
}
catch (Exception Ex)
{
Console.WriteLine(Ex.ToString());
}
Console.WriteLine("end");
Console.ReadLine();
}