导读:本期聚焦于小伙伴创作的《C#的CancellationToken是什么?如何实现可取消的异步操作?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#的CancellationToken是什么?如何实现可取消的异步操作?》有用,将其分享出去将是对创作者最好的鼓励。

C#的CancellationToken是.NET异步编程体系中用于传递取消请求的核心类型,它配合CancellationTokenSource使用,可以在异步操作执行过程中随时触发取消指令,让正在运行的任务及时终止,避免无效的资源消耗。这种机制在网络请求、文件读写、大量数据计算等耗时场景中非常实用,能够有效提升应用的响应性和资源利用率。

C#的CancellationToken是什么?如何实现可取消的异步操作?

CancellationToken的基本概念

CancellationToken是一个轻量级的值类型,它本身不存储取消状态,而是作为取消通知的载体,由CancellationTokenSource创建并分发到各个需要支持取消的操作中。当CancellationTokenSource触发取消时,所有持有对应CancellationToken的操作都能感知到取消请求,进而执行终止逻辑。

它的核心属性有两个:

  • IsCancellationRequested:布尔类型,指示是否已经收到取消请求
  • CanBeCanceled:布尔类型,指示当前令牌是否支持取消操作

配套类型CancellationTokenSource

CancellationTokenSource是创建和管理CancellationToken的工厂类型,负责触发取消请求,它的常用属性和方法如下:

成员说明
Token获取关联的CancellationToken实例
Cancel()触发取消请求,通知所有关联的令牌取消
CancelAfter(TimeSpan)在指定时间后自动触发取消请求
Dispose()释放实例占用的资源

实现可取消异步操作的基本步骤

实现可取消的异步操作通常遵循以下流程:

  1. 创建CancellationTokenSource实例
  2. 获取对应的CancellationToken传递给异步方法
  3. 在异步方法内部定期检查CancellationToken的取消状态
  4. 在需要取消的时候调用CancellationTokenSource的Cancel方法
  5. 操作结束后释放CancellationTokenSource资源

基础示例:可取消的异步延迟操作

下面是一个简单的示例,模拟一个耗时3秒的异步操作,支持在1秒后取消:

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // 创建取消令牌源
        using CancellationTokenSource cts = new CancellationTokenSource();
        // 1秒后自动触发取消
        cts.CancelAfter(TimeSpan.FromSeconds(1));
        
        try
        {
            await LongRunningOperationAsync(cts.Token);
            Console.WriteLine("操作正常完成");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("操作被取消");
        }
    }
    
    static async Task LongRunningOperationAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine("开始执行耗时操作");
        // 模拟耗时操作,同时传入取消令牌
        await Task.Delay(3000, cancellationToken);
        Console.WriteLine("耗时操作执行完成");
    }
}

运行上述代码后,由于1秒就触发了取消,Task.Delay会抛出OperationCanceledException异常,最终输出操作被取消的提示。

循环操作中的取消实现

如果异步操作内部包含循环逻辑,需要在每次循环时检查取消状态,示例代码如下:

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        using CancellationTokenSource cts = new CancellationTokenSource();
        // 2秒后取消
        cts.CancelAfter(2000);
        
        try
        {
            await ProcessLoopAsync(cts.Token);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("循环操作被取消");
        }
    }
    
    static async Task ProcessLoopAsync(CancellationToken cancellationToken)
    {
        for (int i = 0; i < 10; i++)
        {
            // 检查取消请求
            cancellationToken.ThrowIfCancellationRequested();
            
            Console.WriteLine($"处理第 {i + 1} 个任务");
            // 模拟单个任务的耗时
            await Task.Delay(500, cancellationToken);
        }
        Console.WriteLine("所有循环任务完成");
    }
}

代码中ThrowIfCancellationRequested方法会在收到取消请求时直接抛出OperationCanceledException,也可以在循环内手动判断cancellationToken.IsCancellationRequested属性,执行自定义的收尾逻辑后再退出循环。

多任务场景下的取消传递

当有多个并行任务都需要支持取消时,只需要将同一个CancellationToken传递给所有任务即可,示例代码如下:

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        using CancellationTokenSource cts = new CancellationTokenSource();
        // 1.5秒后取消
        cts.CancelAfter(1500);
        
        try
        {
            Task task1 = Task1Async(cts.Token);
            Task task2 = Task2Async(cts.Token);
            Task task3 = Task3Async(cts.Token);
            
            await Task.WhenAll(task1, task2, task3);
            Console.WriteLine("所有任务完成");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("有任务被取消,所有关联任务将收到取消通知");
        }
    }
    
    static async Task Task1Async(CancellationToken cancellationToken)
    {
        await Task.Delay(2000, cancellationToken);
        Console.WriteLine("任务1完成");
    }
    
    static async Task Task2Async(CancellationToken cancellationToken)
    {
        await Task.Delay(1000, cancellationToken);
        Console.WriteLine("任务2完成");
    }
    
    static async Task Task3Async(CancellationToken cancellationToken)
    {
        await Task.Delay(3000, cancellationToken);
        Console.WriteLine("任务3完成");
    }
}

上述代码中三个任务共享同一个取消令牌,1.5秒后取消触发,正在运行的三个任务都会收到取消通知并终止。

取消操作的注意事项

  • CancellationTokenSource使用完毕后需要及时调用Dispose释放资源,建议使用using语句管理生命周期
  • 取消操作是协作式的,只能由操作内部主动检查取消状态并终止,无法从外部强制终止正在运行的任务
  • 如果异步方法内部没有检查取消令牌的逻辑,即使传入了CancellationToken,操作也不会响应取消请求
  • 除了OperationCanceledException,也可以在捕获异常后判断cancellationToken.IsCancellationRequested属性,区分是主动取消还是其他异常
  • 如果需要在取消时执行额外的清理逻辑,可以在捕获OperationCanceledException后编写对应的处理代码

注册取消回调

CancellationToken还支持注册取消时触发的回调函数,适合需要在取消时执行额外操作的场景:

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        using CancellationTokenSource cts = new CancellationTokenSource();
        // 注册取消回调
        cts.Token.Register(() =>
        {
            Console.WriteLine("收到取消通知,执行清理逻辑");
        });
        
        // 1秒后取消
        cts.CancelAfter(1000);
        
        try
        {
            await Task.Delay(3000, cts.Token);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("操作被取消");
        }
    }
}

运行后会在取消触发时先执行注册的回调方法,再抛出异常,方便开发者执行资源释放、状态重置等清理操作。

CancellationToken异步操作可取消任务C#异步编程修改时间:2026-06-20 16:09:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。