CancellationTokenSource 与 CancellationTokenSourceToken
1. CancellationTokenSource 和 CancellationToken 是什么关系
可以理解成这样:
-
CancellationTokenSource(CTS) → “遥控器”
它是发信号的人,我们可以调用.Cancel()来通知任务:“你该停了”。 -
CancellationToken(Token) → “遥控器的接收器”
它只是一个只读的信号,任务内部只能用它来接收是否被取消,不能去取消别人。
CancellationTokenSource ----产生----> CancellationToken
2. 什么时候传 CancellationTokenSource
一般不建议跨方法传 CancellationTokenSource,因为:
- CTS 有
.Cancel()和.Dispose()方法,生命周期很容易被别人乱操作。 - 如果多个方法共享同一个 CTS,很容易出现遇到的 Dispose 冲突。
典型的例外场景:
当调用方需要在方法内部主动触发取消,才会传 CTS,比如:
public void StartSomething(CancellationTokenSource cts) {
// 方法内部某个条件触发
if (需要取消) {
cts.Cancel();
}
}
这种情况比较少见,大多数时候我们只是想发取消信号的人自己管理 CTS,不让别人动它。
3. 什么时候传 CancellationToken
99% 的异步任务传的应该是 CancellationToken 而不是 CTS,因为:
- Token 不能被
.Cancel()或.Dispose(),所以任务只能用它接收取消信号,而不会乱动。 - 调用方控制 CTS,保证线程安全,方法内部不需要担心 Dispose 冲突。
例如:
public async Task DoWorkAsync(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
// 执行某些任务
await Task.Delay(100, token); // 如果取消,这里会抛 TaskCanceledException
}
}
调用方:
var cts = new CancellationTokenSource();
await DoWorkAsync(cts.Token); // 只传 Token
4. 总结口诀
- 要控制任务生命周期 → 自己持有
CancellationTokenSource(发信号的人) - 只需要监听取消信号 → 只传
CancellationToken(收信号的人) - 不要跨方法传 CTS,除非方法里确实需要主动
.Cancel()它(很少)

浙公网安备 33010602011771号