[英]Why is Task.IsCanceled Not True?
I have a simple program here 我这里有一个简单的程序
private static void CancellingSingleTask()
{
DateTime whenStarted = DateTime.Now;
Console.WriteLine("[{0}] - Main: Started", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;
Task task = Task.Factory.StartNew(() =>
{
int? taskId = Task.CurrentId;
Console.WriteLine("[{0}] - Task - [{1}]: Started", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
Thread.Sleep(2000);
if (ct.IsCancellationRequested)
{
Console.WriteLine("[{0}] - Task - [{1}]: Cancellation Requested", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
throw new OperationCanceledException();
}
Console.WriteLine("[{0}] - Task - [{1}]: No Cancellation Requested", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
}, ct);
Action Print = () =>
{
Console.WriteLine("[{0}] - Main: Task.IsCanceled = [{1}] Task.IsFaulted = [{2}] Task.IsCompleted = [{3}] Task.Status = [{4}]", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks),
task.IsCanceled, task.IsFaulted, task.IsCompleted, task.Status);
};
Console.WriteLine("[{0}] - Main: Started New Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
Print();
Thread.Sleep(1000);
Console.WriteLine("[{0}] - Main: Cancelling Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
cts.Cancel();
Thread.Sleep(2000);
Console.WriteLine("[{0}] - Main: After Cancelling Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
Print();
try
{
Console.WriteLine("[{0}] - Main: Waiting For Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
task.Wait();
Console.WriteLine("[{0}] - Main: After Waiting For Task", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
Print();
}
catch (AggregateException aggregateException)
{
Thread.Sleep(2000);
Console.WriteLine("[{0}] - Main: In Catch Block", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks));
Print();
foreach (var exception in aggregateException.InnerExceptions)
{
Console.WriteLine("[{0}] - Main: Received Exception In Task [{1}]", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), exception.Message);
}
}
}
Sample Output 样本输出
[00:00:00.0010000] - Main: Started [00:00:00.0010000]-主程序:已启动
[00:00:00.0040002] - Main: Started New Task [00:00:00.0040002]-主要:已开始新任务
[00:00:00.0060003] - Main: IsCanceled = [False] IsFaulted = [False] IsCompleted = [False] Status = [Running] [00:00:00.0060003]-Main:IsCanceled = [False] IsFaulted = [False] IsCompleted = [False]状态= [Running]
[00:00:00.0070004] - Task - [1]: Started [00:00:00.0070004]-任务-[1]:已开始
[00:00:01.0070576] - Main: Cancelling Task [00:00:01.0070576]-主程序:取消任务
[00:00:02.0071148] - Task - [1]: Cancellation Requested [00:00:02.0071148]-任务-[1]:请求取消
[00:00:03.0111722] - Main: After Cancelling Task [00:00:03.0111722]-主程序:取消任务后
[00:00:03.0111722] - Main: IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted] [00:00:03.0111722]-Main:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:03.0111722] - Main: Waiting For Task [00:00:03.0111722]-主程序:等待任务
[00:00:05.0112866] - Main: In Catch Block [00:00:05.0112866]-主要:在接球区
[00:00:05.0112866] - Main: IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted] [00:00:05.0112866]-Main:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:05.0112866] - Main: Received Exception In Task [The operation was canceled.] [00:00:05.0112866]-主操作:任务中收到异常[操作已取消。
I never see the Task.IsCanceled Set to true, am I making a mistake or missing something obvious. 我从没看到Task.IsCanceled设置为true,是我犯了一个错误还是遗漏了一些明显的东西。 I have done a bit of research/searching on this issue but was not able to find a conclusive answer.
我已经对此问题进行了一些研究/搜索,但是找不到最终的答案。
Note: Related Questions on StackOverFlow Cancellation of a task task IsCanceled is false, while I canceled Task.IsCancelled doesn't work 注意:有关StackOverFlow的相关问题取消任务 任务IsCanceled为false,而我取消了 Task.IsCancelled则不起作用
I suppose you should pass the CancellationToken
to the constructor of OperationCanceledException
. 我想您应该将
CancellationToken
传递给OperationCanceledException
的构造函数。
if (ct.IsCancellationRequested)
{
Console.WriteLine("[{0}] - Task - [{1}]: Cancellation Requested", TimeSpan.FromTicks(DateTime.Now.Ticks - whenStarted.Ticks), taskId);
throw new OperationCanceledException(ct);
}
TPL will check whether both CancellationToken
are same, if so it will mark task as Cancelled
in your case it is not and so TPL assumes your task is not cancelled. TPL将检查两个
CancellationToken
是否相同,如果是这样,它将在您的情况下将其标记为“ Cancelled
,因此TPL假定您的任务未取消。
or even better use ThrowIfCancellationRequested
method, as simple as that 甚至更好地使用
ThrowIfCancellationRequested
方法,就像那样简单
ct.ThrowIfCancellationRequested();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.