CancellationToken 模式与协作式取消
传递并遵守 CancellationToken:创建 CTS,轮询取消状态或因取消而抛出异常,将其传给异步 API,并通过注册进行清理。
CancellationToken 模式与协作式取消 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 3 节课。
协作式取消
目标:以协作方式取消工作。
- 创建一个 CancellationTokenSource
- 向下传递 CancellationToken
- 检查 IsCancellationRequested,或调用 ThrowIfCancellationRequested()
- 快速且妥善地响应取消
调用方驱动的取消
创建一个 CancellationTokenSource,传递令牌,并从调用方执行取消;被调用方会抛出 OperationCanceledException。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task WorkAsync(CancellationToken ct)
{
// Poll occasionally; throw to end cooperatively
for (int i = 0; i < 5; i++)
{
ct.ThrowIfCancellationRequested();
Console.WriteLine("Step " + i);
await Task.Delay(100, ct); // pass token to async API
}
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Task t = WorkAsync(cts.Token);
// Cancel after a short delay (simulated user action)
Thread.Sleep(180);
cts.Cancel();
try
{
t.GetAwaiter().GetResult();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
}
}
转发令牌
通过每一层异步调用转发令牌,以便内部调用能够及时停止。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task<string> FetchAsync(CancellationToken ct)
{
await Task.Delay(80, ct); // pretend I/O
ct.ThrowIfCancellationRequested();
return "data";
}
static async Task<string> ProcessAsync(CancellationToken ct)
{
string raw = await FetchAsync(ct); // forward token
await Task.Delay(80, ct);
return raw.ToUpperInvariant();
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Task<string> job = ProcessAsync(cts.Token);
cts.CancelAfter(100); // schedule a cancellation
try
{
Console.WriteLine(job.GetAwaiter().GetResult());
}
catch (OperationCanceledException)
{
Console.WriteLine("Pipeline canceled");
}
}
}
令牌.Register 清理
使用 令牌.Register 附加一个小型清理操作,在请求取消时运行。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task UseRegistrationAsync(CancellationToken ct)
{
using (ct.Register(() => Console.WriteLine("Cleanup: releasing temp resources")))
{
for (int i = 0; i < 3; i++)
{
ct.ThrowIfCancellationRequested();
await Task.Delay(120, ct);
Console.WriteLine("Tick " + i);
}
}
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Task t = UseRegistrationAsync(cts.Token);
Thread.Sleep(150);
cts.Cancel();
try { t.GetAwaiter().GetResult(); }
catch (OperationCanceledException) { Console.WriteLine("Canceled with cleanup"); }
}
}
链接源
CreateLinkedTokenSource 会将多个信号(例如用户取消和超时)合并为一个令牌。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task WorkAsync(CancellationToken ct)
{
await Task.Delay(500, ct);
Console.WriteLine("Finished work");
}
public static void Main(string[] args)
{
var parent = new CancellationTokenSource();
var timeout = new CancellationTokenSource();
timeout.CancelAfter(200);
// Link both sources: cancel if parent OR timeout requests
var linked = CancellationTokenSource.CreateLinkedTokenSource(parent.Token, timeout.Token);
Task t = WorkAsync(linked.Token);
try { t.GetAwaiter().GetResult(); }
catch (OperationCanceledException) { Console.WriteLine("Canceled by parent/timeout"); }
finally { linked.Dispose(); parent.Dispose(); timeout.Dispose(); }
}
}
最佳实践
提示:
- 将令牌传递给异步 API(Task.Delay、I/O),以便它们及时停止。
- 抛出 OperationCanceledException 来结束工作;不要吞掉此异常。
- 如果 CancellationTokenSource 持有计时器或注册项,请将其释放。
- 保持处理程序快速;在 Register 中只执行最少的工作。
协作式取消规则
回顾
回顾:让取消采用协作方式——传递令牌,进行轮询或调用 ThrowIfCancellationRequested,附加小型清理操作,并链接源以组合多个信号。
常见问题解答
「CancellationToken 模式与协作式取消」课时是免费的吗?
是的 — 「CancellationToken 模式与协作式取消」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 3 节课。
「CancellationToken 模式与协作式取消」这节课中我会学到什么?
传递并遵守 CancellationToken:创建 CTS,轮询取消状态或因取消而抛出异常,将其传给异步 API,并通过注册进行清理。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 3 节。
「CancellationToken 模式与协作式取消」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- CancellationToken 模式与协作式取消
- 超时、IProgress 与异步可释放对象(模拟)
- 弹性基础:重试与退避