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并执行清理操作,确保取消过程安全完整。

使用
CancellationToken
可以优雅地取消 C# 中的异步任务。它提供了一种协作式的取消机制,允许任务在取消请求时安全地停止执行。
解决方案:
CancellationToken的核心在于
CancellationTokenSource
和
CancellationToken
。
CancellationTokenSource
负责发出取消信号,而
CancellationToken
则传递给异步任务,让任务监听取消信号。
创建
CancellationTokenSource
:
CancellationTokenSource cts = new CancellationTokenSource();
获取
CancellationToken
:
CancellationToken token = cts.Token;
将
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."); }}
启动异步任务:
Task task = MyAsyncTask(token);
请求取消:
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会将任务调度到线程池,而线程池线程是后台线程。如果主线程退出,后台线程可能会被强制终止,导致未处理的异常。
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如何取消异步任务?的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1439341.html
微信扫一扫
支付宝扫一扫