我读过文档说将状态设置为“已取消”需要三个条件:
OperationCanceledException
(或其派生的异常类型,如TaskCanceledException
)被抛出token.IsCancellationRequested
是真的token
传递给的委托与在任务创建时传递的参数OperationCanceledException
相同token
但是下面的示例直接抛出,没有任何 token,但取消成功。是因为 token 是一个结构体,所以默认值总是满足最后两个条件吗?我对这个想法没有信心,如果我错了,希望得到一些解释
var task = Task.Run(() =>
{
throw new OperationCanceledException();
});
try
{
task.Wait();
}
catch (AggregateException)
{
Console.WriteLine(task.Status); // Cancelled
}
Task.Run
这是因为编译器选择了用于lambda的重载,async
例如然而,在您的情况下,这会出现令人惊讶的行为,因为您应该测试原始
Task
行为而不是方法行为async
。过载
function
包装了您的原始任务,并具有如下逻辑来处理它并为您提供“已处理的任务”:基本上,如果发生异常,它会将
Faulted
内部任务转换为外部任务。Cancelled
OperationCanceledException
如果你想实验和测试一些东西,请确保选择第一个重载
action
- 这样就不会发生这样的魔法: