0

0

C#的CancellationToken如何取消异步任务?

幻夢星雲

幻夢星雲

发布时间:2025-09-03 08:52:01

|

558人浏览过

|

来源于php中文网

原创

cancellationtoken通过cancellationtokensource和cancellationtoken实现协作式取消机制,前者发出取消信号,后者传递给异步任务监听信号;2. 创建cancellationtokensource并获取其token,将token传入异步方法,在任务中通过throwifcancellationrequested或iscancellationrequested检查取消请求,并在task.delay等异步操作中传入token以响应取消;3. 调用cancellationtokensource的cancel方法可触发所有关联任务的取消,cancelafter可设置延迟自动取消;4. 多个并发任务可共享同一cancellationtoken,实现集中取消控制;5. 使用using语句或try-finally确保cancellationtokensource被正确dispose,防止资源泄漏;6. 异步任务应捕获operationcanceledexception并执行清理操作,确保取消过程安全完整。

C#的CancellationToken如何取消异步任务?

使用

CancellationToken
可以优雅地取消 C# 中的异步任务。它提供了一种协作式的取消机制,允许任务在取消请求时安全地停止执行。

解决方案:

CancellationToken的核心在于

CancellationTokenSource
CancellationToken
CancellationTokenSource
负责发出取消信号,而
CancellationToken
则传递给异步任务,让任务监听取消信号。

  1. 创建

    CancellationTokenSource
    :

    CancellationTokenSource cts = new CancellationTokenSource();
  2. 获取

    CancellationToken
    :

    CancellationToken token = cts.Token;
  3. CancellationToken
    传递给异步任务:

    async Task MyAsyncTask(CancellationToken cancellationToken)
    {
        try
        {
            for (int i = 0; i < 100; i++)
            {
                // 检查是否已请求取消
                cancellationToken.ThrowIfCancellationRequested();
    
                // 执行一些工作
                Console.WriteLine($"Task running: {i}");
                await Task.Delay(100, cancellationToken); // 异步等待,并监听取消信号
            }
            Console.WriteLine("Task completed successfully.");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Task cancelled.");
        }
    }
  4. 启动异步任务:

    Task task = MyAsyncTask(token);
  5. 请求取消:

    cts.Cancel(); // 发出取消信号

关键点在于

cancellationToken.ThrowIfCancellationRequested()
Task.Delay(..., cancellationToken)
。前者在每次迭代中检查是否已请求取消,如果是,则抛出
OperationCanceledException
。后者在异步等待期间也监听取消信号,如果收到取消信号,也会抛出
OperationCanceledException

异步任务应该捕获

OperationCanceledException
并进行清理工作。

CancellationTokenSource的CancelAfter方法可以在指定时间后自动取消任务。

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

CancellationToken
也可以与
async/await
结合使用,这使得取消操作在异步代码中非常方便。 如果没有
CancellationToken
,取消异步操作会变得相当复杂,可能需要使用超时或其他技巧。

CancellationToken与Task.Run结合使用时,需要特别注意。Task.Run会将任务调度到线程池,而线程池线程是后台线程。如果主线程退出,后台线程可能会被强制终止,导致未处理的异常。

MaxAI
MaxAI

MaxAI.me是一款功能强大的浏览器AI插件,集成了多种AI模型。

下载

CancellationTokenSource的Token属性是一个只读属性,这意味着一旦创建,就不能更改与特定任务关联的CancellationToken。 如果需要为同一任务创建新的取消令牌,则必须创建新的CancellationTokenSource。

CancellationToken如何处理多个并发任务?

对于多个并发任务,可以为每个任务传递同一个

CancellationToken
。当调用
CancellationTokenSource.Cancel()
时,所有使用该
CancellationToken
的任务都会收到取消信号。这是一种高效且集中的取消方式。

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task task1 = MyAsyncTask(token);
Task task2 = MyAsyncTask(token);

// ... 一段时间后

cts.Cancel(); // 同时取消 task1 和 task2

需要注意的是,每个任务都需要正确地处理

OperationCanceledException
,否则未处理的异常可能会导致程序崩溃。

CancellationToken的IsCancellationRequested属性有什么用?

IsCancellationRequested
属性用于检查是否已请求取消,但不会抛出异常。这允许任务在执行过程中根据取消状态执行不同的操作,而不是立即停止执行。

async Task MyAsyncTask(CancellationToken cancellationToken)
{
    while (!cancellationToken.IsCancellationRequested)
    {
        // 执行一些工作
        Console.WriteLine("Task running...");
        await Task.Delay(100);

        // 检查是否已请求取消,并执行清理工作
        if (cancellationToken.IsCancellationRequested)
        {
            Console.WriteLine("Cancellation requested. Cleaning up...");
            // 执行清理操作
            break;
        }
    }
    Console.WriteLine("Task finished.");
}

使用

IsCancellationRequested
可以更灵活地控制任务的取消行为,例如在完成当前迭代后再停止执行。

如何处理CancellationTokenSource的Dispose?

CancellationTokenSource
实现了
IDisposable
接口,因此在使用完毕后应该调用
Dispose()
方法来释放资源。这可以防止内存泄漏和其他资源问题。

可以使用

using
语句来确保
CancellationTokenSource
在使用完毕后被正确地释放。

using (CancellationTokenSource cts = new CancellationTokenSource())
{
    CancellationToken token = cts.Token;
    Task task = MyAsyncTask(token);

    // ... 一段时间后

    cts.Cancel();
    await task;
} // cts.Dispose() 会在这里被自动调用

如果不使用

using
语句,则需要手动调用
Dispose()
方法。

CancellationTokenSource cts = new CancellationTokenSource();
try
{
    CancellationToken token = cts.Token;
    Task task = MyAsyncTask(token);

    // ... 一段时间后

    cts.Cancel();
    await task;
}
finally
{
    cts.Dispose();
}

无论哪种方式,都要确保

Dispose()
方法被调用,以避免资源泄漏。 特别是在长时间运行的应用程序中,忽略
Dispose()
可能会导致严重的问题。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6097

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

807

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1062

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1253

2024.03.01

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1023

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

444

2025.12.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

11

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7万人学习

C 教程
C 教程

共75课时 | 4.1万人学习

C++教程
C++教程

共115课时 | 12.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号