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

幻夢星雲
发布: 2025-09-03 08:52:01
原创
549人浏览过

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会将任务调度到线程池,而线程池线程是后台线程。如果主线程退出,后台线程可能会被强制终止,导致未处理的异常。

如知AI笔记
如知AI笔记

如知笔记——支持markdown的在线笔记,支持ai智能写作、AI搜索,支持DeepseekR1满血大模型

如知AI笔记 27
查看详情 如知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()
登录后复制
可能会导致严重的问题。

以上就是C#的CancellationToken如何取消异步任务?的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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