gpt4 book ai didi

c# - 为什么 Task.IsCanceled 不正确?

转载 作者:太空宇宙 更新时间:2023-11-03 18:08:47 26 4
gpt4 key购买 nike

我这里有一个简单的程序

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);
}
}

}

示例输出
[00:00:00.0010000] - 主线:开始
[00:00:00.0040002] - 主要:开始新任务
[00:00:00.0060003] - 主要:IsCanceled = [False] IsFaulted = [False] IsCompleted = [False] Status = [Running]
[00:00:00.0070004] - 任务 - [1]:开始
[00:00:01.0070576] - 主要:取消任务
[00:00:02.0071148] - 任务 - [1]:请求取消
[00:00:03.0111722] - 主要:取消任务后
[00:00:03.0111722] - 主要:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:03.0111722] - 主要:WAITING任务
[00:00:05.0112866] - 主要:在 Catch block 中
[00:00:05.0112866] - 主要:IsCanceled = [False] IsFaulted = [True] IsCompleted = [True] Status = [Faulted]
[00:00:05.0112866] - Main:在任务中收到异常 [操作已取消。]

我从来没有看到 Task.IsCanceled 设置为 true,我是在犯错还是遗漏了一些明显的东西。我对这个问题进行了一些研究/搜索,但未能找到决定性的答案。

注意:StackOverFlow 上的相关问题 Cancellation of a task task IsCanceled is false, while I canceled Task.IsCancelled doesn't work

最佳答案

我想您应该将 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 将检查两个 CancellationToken 是否相同,如果相同,它会将任务标记为 Cancelled 在您的情况下它不是,因此 TPL 假定您的任务未取消。

或者甚至更好地使用 ThrowIfCancellationRequested 方法,就这么简单

ct.ThrowIfCancellationRequested();

关于c# - 为什么 Task.IsCanceled 不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20782110/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com