在任务中调用 CancellationTokenSource.Cancel() 不会将 Task.IsCanceled 设置为 true
Calling CancellationTokenSource.Cancel() within a task does not set Task.IsCanceled to true
如果我在与取消标记关联的任务中调用 cancellationTokenSource.Cancel
,则会正确抛出 OperationCancelledException
,但是,task.IsCanceled
并不总是更新并设置为 true
, 正如所料。
可以通过以下 nUnit 测试快速证明问题:
var cancellationTokenSource = new CancellationTokenSource();
Task task = Task.Factory.StartNew(() =>
{
cancellationTokenSource.Cancel();
cancellationTokenSource.Token.ThrowIfCancellationRequested();
},
cancellationTokenSource.Token);
try
{
task.Wait(cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
}
if (task.IsCanceled)
{
Assert.Pass();
}
else
{
Assert.Fail();
}
当我运行这个测试时,测试通过了,然而,当我DEBUG这个测试(使用Resharper测试运行ner)时,测试失败了。
我认为这与 Resharper 没有任何关系,我认为 Resharper 可能只是创造了一些条件,可能会暴露 .Net 中的问题。或者,也许我只是在做一些完全错误的事情……有什么见解吗?
等待 Task
时不要使用取消标记。它导致 Wait
在设置任务状态之前抛出并继续执行断言。
这两件事是并行发生的,所以它实际上是关于它是否发生的竞争条件,因此你在调试时试图复制这些问题和正确的行为。
如果我在与取消标记关联的任务中调用 cancellationTokenSource.Cancel
,则会正确抛出 OperationCancelledException
,但是,task.IsCanceled
并不总是更新并设置为 true
, 正如所料。
可以通过以下 nUnit 测试快速证明问题:
var cancellationTokenSource = new CancellationTokenSource();
Task task = Task.Factory.StartNew(() =>
{
cancellationTokenSource.Cancel();
cancellationTokenSource.Token.ThrowIfCancellationRequested();
},
cancellationTokenSource.Token);
try
{
task.Wait(cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
}
if (task.IsCanceled)
{
Assert.Pass();
}
else
{
Assert.Fail();
}
当我运行这个测试时,测试通过了,然而,当我DEBUG这个测试(使用Resharper测试运行ner)时,测试失败了。
我认为这与 Resharper 没有任何关系,我认为 Resharper 可能只是创造了一些条件,可能会暴露 .Net 中的问题。或者,也许我只是在做一些完全错误的事情……有什么见解吗?
等待 Task
时不要使用取消标记。它导致 Wait
在设置任务状态之前抛出并继续执行断言。
这两件事是并行发生的,所以它实际上是关于它是否发生的竞争条件,因此你在调试时试图复制这些问题和正确的行为。