C# CancellationTokenSource CancellationToken Task.Run传入token 取消令牌


CancellationTokenSourceC# 中用于实现异步操作取消的核心类,它生成 CancellationToken 对象,该对象可以传递给异步方法,并在异步方法内部检查是否收到取消请求。

基本使用方法

创建 CancellationTokenSource

CancellationTokenSource cts = new CancellationTokenSource();

获取 CancellationToken

CancellationToken token = cts.Token;

CancellationToken 传递给任务

Task task = Task.Run(() => DoWork(token), token);

注意

// 传递给
Task.Run(() => {
	Foo();
}, token);
// 的token只是在Task开始运行前检查一次是否取消,如果取消,Run不了一点

在任务中检查取消状态

static void DoWork(CancellationToken token)
{
    for (int i = 0; i < 10; i++)
    {
    	// 检查是否收到取消请求
         if (token.IsCancellationRequested)
        	token.ThrowIfCancellationRequested();// 此处抛出异常,外面用try catch捕获
        	
        Console.WriteLine($"Task working... {i}");
        Thread.Sleep(500); // 模拟耗时操作
    }
}

请求取消

cts.Cancel();

处理取消异常

try
{
    await task;
}
catch (OperationCanceledException)
{
    Console.WriteLine("Task was cancelled.");
}

高级用法

设置超时自动取消

CancellationTokenSource cts = new CancellationTokenSource(5000); // 5秒后自动取消
CancellationToken token = cts.Token;

或者使用 CancelAfter 方法

CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000); // 5秒后自动取消

关联多个取消令牌

CancellationTokenSource tokenSource1 = new CancellationTokenSource();
CancellationTokenSource tokenSource2 = new CancellationTokenSource();

CancellationTokenSource linkedTokenSource =
	CancellationTokenSource.CreateLinkedTokenSource(
		tokenSource1.Token, 
		tokenSource2.Token
	);
	
linkedTokenSource.Token.Register(() => 
	Console.WriteLine("Linked token cancelled")
);

tokenSource1.Cancel(); // 会触发 linkedTokenSource 的取消

注册回调

token.Register(() => Console.WriteLine("Cancellation requested"));

注意事项

  • 取消操作是协作式的,任务必须主动检查 CancellationToken 的状态。
  • CancellationTokenSourceCancel 方法会触发所有注册的回调。
  • 默认情况下,CancellationTokenSource 是一次性的,取消后无法重置。

通过这些方法,CancellationTokenSource 可以有效地管理异步操作的取消。

<think>好的,我现在需要帮助用户理解如何在C#中使用CancellationTokenSourceCancellationToken取消请求。首先,我应该回忆一下这两个类的基本用法和它们之间的关系。 用户给出的代码片段是: CancellationTokenSource tokensourceRec3 = new CancellationTokenSource(); CancellationToken cancellationToken = tokensourceRec3.Token; 他们的主要问题是如何取消请求。我知道,CancellationTokenSource负责生成CancellationToken,并通过调用Cancel()方法来触发取消。而CancellationToken则用于传递给需要支持取消的方法,让这些方法能够监听到取消请求。 接下来,我需要分步骤解释如何实现取消。首先,用户需要创建CancellationTokenSource实例,然后获取它的Token属性得到CancellationToken,并将其传递给异步任务,比如HttpClient的请求或者Task.Run中的操作。 然后,当需要取消时,调用CancellationTokenSource的Cancel()方法。这时候,CancellationToken的IsCancellationRequested属性会变为true,执行中的任务需要定期检查这个属性,或者调用ThrowIfCancellationRequested()来抛出OperationCanceledException异常,从而终止操作。 需要注意的几点包括:异常处理,资源释放,以及可能的多次取消调用。例如,如果任务已经被取消,再次调用Cancel()不会有额外效果。另外,CancellationTokenSource实现了IDisposable,所以在不再需要时应调用Dispose()释放资源,特别是当使用了计时器等内部资源时。 可能用户会想知道具体的代码示例,比如如何在异步方法中使用Token,如何处理取消时的异常,以及如何确保资源正确释放。因此,我应该提供一个简单的示例,演示如何启动一个任务,传递Token,并在某个条件下取消它,同时捕获异常。 还需要提醒用户,不是所有的API都支持CancellationToken,但很多现代的.NET库,尤其是异步方法,都支持。例如,HttpClient的SendAsync方法可以接受CancellationToken,这样用户可以在请求过程中取消。 总结步骤应该是:创建CancellationTokenSource,获取Token,传递Token给任务,在需要时调用Cancel(),处理取消逻辑,最后释放资源。同时,要强调异常处理的重要性,避免程序崩溃。 最后,检查是否有遗漏点,比如取消后的状态,或者如何结合使用多个Token,但用户的问题可能只需要基础用法,所以保持回答简洁明了,重点放在如何取消请求的步骤和示例上。</think>在 C# 中,`CancellationTokenSource` 和 `CancellationToken` 是用于实现协作式取消请求的机制。以下是逐步说明和操作示例: --- ### **步骤 1:创建 CancellationTokenSource** ```csharp CancellationTokenSource tokensourceRec3 = new CancellationTokenSource(); CancellationToken cancellationToken = tokensourceRec3.Token; ``` - `CancellationTokenSource` 是取消请求的**控制中心** - `Token` 属性生成一个 `CancellationToken`,用于传递给需要支持取消的方法 --- ### **步骤 2:将 Token 传递给异步方法** ```csharp async Task DoWorkAsync(CancellationToken ct) { while (!ct.IsCancellationRequested) { // 模拟耗时操作 await Task.Delay(1000); Console.WriteLine("Working..."); } Console.WriteLine("任务已取消!"); } // 启动任务时传入 Token var task = DoWorkAsync(cancellationToken); ``` --- ### **步骤 3:触发取消请求** ```csharp // 手动取消(例如通过按钮点击或条件触发) tokensourceRec3.Cancel(); // 也可以设置自动取消(例如 5 秒后自动触发) tokensourceRec3.CancelAfter(5000); ``` - 调用 `Cancel()` 方法后,所有使用该 Token 的任务会收到取消请求 - `CancelAfter()` 可实现延时自动取消 --- ### **步骤 4:处理取消请求** 在任务代码中可通过两种方式响应取消: #### **方式 1:轮询检查** ```csharp if (ct.IsCancellationRequested) { // 清理资源 return; } ``` #### **方式 2:抛出异常(推荐)** ```csharp ct.ThrowIfCancellationRequested(); ``` - 会抛出 `OperationCanceledException`,需用 try-catch 处理 --- ### **完整示例代码** ```csharp using System; using System.Threading; using System.Threading.Tasks; class Program { static async Task Main() { // 1. 创建取消控制器 var cts = new CancellationTokenSource(); var token = cts.Token; // 2. 启动异步任务 var task = Task.Run(async () => { try { while (true) { token.ThrowIfCancellationRequested(); await Task.Delay(1000, token); Console.WriteLine("持续工作中..."); } } catch (OperationCanceledException) { Console.WriteLine("优雅地处理了取消请求"); } }, token); // 3. 模拟 3 秒后取消 await Task.Delay(3000); cts.Cancel(); // 4. 等待任务结束 await task; } } ``` --- ### **关键注意事项** 1. **资源释放**:`CancellationTokenSource` 实现了 `IDisposable`,不再使用时调用 `cts.Dispose()` 2. **异常处理**:捕获 `OperationCanceledException` 以响应取消 3. **线程安全**:`Cancel()` 可在任意线程调用 4. **不可重用**:一个 `CancellationTokenSource` 取消后不能再次使用,需新建实例 --- ### **典型应用场景** - 取消 HTTP 请求(如 `HttpClient.SendAsync`) - 停止后台任务 - 中断长时间运行的操作 - 用户主动取消操作(如点击取消按钮) 通过这种机制,您可以实现高效、可控的任务取消逻辑,避免资源泄漏和程序无响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值