问题描述
某些 System.Threading.Tasks.Task
构造函数将 CancellationToken
作为参数:
Certain System.Threading.Tasks.Task
constructors take a CancellationToken
as a parameter:
CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);
让我感到困惑的是,没有办法从内部方法体中实际获取传入的令牌(例如,没有像 Task.CurrentTask.CancellationToken
).令牌必须通过某种其他机制提供,例如状态对象或在 lambda 中捕获.
What baffles me about this is that there is no way from inside the method body to actually get at the token passed in (e.g., nothing like Task.CurrentTask.CancellationToken
). The token has to be provided through some other mechanism, such as the state object or captured in a lambda.
那么在构造函数中提供取消令牌的目的是什么?
So what purpose does providing the cancellation token in the constructor serve?
推荐答案
将 CancellationToken
传递到 Task
构造函数中,将其与任务相关联.
Passing a CancellationToken
into the Task
constructor associates it with the task.
这有两个主要好处:
- 如果令牌在
Task
开始执行之前请求取消,Task
将不会执行.而不是过渡到Running
,它会立即过渡到Canceled
.这避免了运行任务的成本,如果它只是在运行时被取消无论如何. - 如果任务主体也在监视取消标记并抛出包含该标记的
OperationCanceledException
(这就是ThrowIfCancellationRequested
所做的),然后当任务看到OperationCanceledException
,它检查OperationCanceledException
的token是否与Task的token匹配令牌.如果是,则该例外被视为对合作取消和Task
转换到Canceled
状态(而不是Faulted
状态).
- If the token has cancellation requested prior to the
Task
starting to execute, theTask
won't execute. Rather than transitioning toRunning
, it'll immediately transition toCanceled
. This avoids the costs of running the task if it would just be canceled while running anyway. - If the body of the task is also monitoring the cancellation token and throws an
OperationCanceledException
containing that token (which is whatThrowIfCancellationRequested
does), then when the task sees thatOperationCanceledException
, it checks whether theOperationCanceledException
's token matches the Task's token. If it does, that exception is viewed as an acknowledgement of cooperative cancellation and theTask
transitions to theCanceled
state (rather than theFaulted
state).
这篇关于任务构造函数中的取消标记:为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!