当我创建一个任务然后取消它时,它的状态显示已取消,但将其与 TaskStatus.Canceled returns false 进行比较
When I create a task and then cancel it, it status says cancelled, but comparing it to TaskStatus.Canceled returns false
我不明白为什么,当 task.Status = cancelled
iscancelled 是 false
var cancellation = new CancellationTokenSource();
task = Task.Run(() => GetValueToPrint(), cancellation.Token);
cancellation.Cancel();
bool iscancelled = task.Status == TaskStatus.Canceled;
有什么想法吗?
谢谢
task.Status
仅当满足两个条件之一时才等于 Canceled
。
- 在调用
Task.Run
之前,取消标记已经处于取消状态。
Task.Run
中 运行 的代码将 OperationCanceledException and the token that was passed in to the constructor of the exception was the same token (or a linked token 扔给了相同的标记)传递给 Task.Run
您没有上述任何一种情况,因此您的任务在检查时可能处于 Running
或 RanToCompletion
状态。
如果你想在 GetValueToPrint()
启动后取消它,你必须将相同的标记作为参数传递给它,然后在整个方法中你需要调用 token.ThrowIfCancellationRequested()
在可以取消的地方传递令牌。这样做会导致您在我上面列出的两个选项中排名第二。
private string GetValueToPrint(CancellationToken token)
{
for(int i = 0; i < 10; i++)
{
Console.WriteLine("Loop");
token.ThrowIfCancellationRequested()
Thread.Sleep(1000);
}
return "42";
}
private void Example()
{
var cancellation = new CancellationTokenSource();
task = Task.Run(() => GetValueToPrint(cancellation.Token), cancellation.Token);
Thread.Sleep(5000);
cancellation.Cancel();
bool iscancelled = task.Status == TaskStatus.Canceled;
Console.WriteLine(iscancelled);
}
你会看到 "Loop" 打印了 4-6 次(这有点竞争条件)那么 iscancelled
就是真的;
我不明白为什么,当 task.Status = cancelled
iscancelled 是 false var cancellation = new CancellationTokenSource();
task = Task.Run(() => GetValueToPrint(), cancellation.Token);
cancellation.Cancel();
bool iscancelled = task.Status == TaskStatus.Canceled;
有什么想法吗?
谢谢
task.Status
仅当满足两个条件之一时才等于 Canceled
。
- 在调用
Task.Run
之前,取消标记已经处于取消状态。 Task.Run
中 运行 的代码将 OperationCanceledException and the token that was passed in to the constructor of the exception was the same token (or a linked token 扔给了相同的标记)传递给Task.Run
您没有上述任何一种情况,因此您的任务在检查时可能处于 Running
或 RanToCompletion
状态。
如果你想在 GetValueToPrint()
启动后取消它,你必须将相同的标记作为参数传递给它,然后在整个方法中你需要调用 token.ThrowIfCancellationRequested()
在可以取消的地方传递令牌。这样做会导致您在我上面列出的两个选项中排名第二。
private string GetValueToPrint(CancellationToken token)
{
for(int i = 0; i < 10; i++)
{
Console.WriteLine("Loop");
token.ThrowIfCancellationRequested()
Thread.Sleep(1000);
}
return "42";
}
private void Example()
{
var cancellation = new CancellationTokenSource();
task = Task.Run(() => GetValueToPrint(cancellation.Token), cancellation.Token);
Thread.Sleep(5000);
cancellation.Cancel();
bool iscancelled = task.Status == TaskStatus.Canceled;
Console.WriteLine(iscancelled);
}
你会看到 "Loop" 打印了 4-6 次(这有点竞争条件)那么 iscancelled
就是真的;