在C#中使用 CancellationToken 处理异步任务
在 .NET Core 中使用异步编程已经很普遍了, 你在项目中随处可见 async 和 await,它简化了异步操作,允许开发人员,使用同步的方式编写异步代码,你会发现在大部分的异步方法中,都提供了CancellationToken参数,本文主要介绍下 CancellationTokenSource 和 CancellationToken在异步任务中的使用。
手动取消任务
创建一个 CancellationTokenSource,然后调用异步方法时,传入 CancellationToken,它是一个轻量级对象,可以通知请求是否已取消,我们可以手动调用 cts.Cancel() 来取消任务,为了方面演示,这里我有用到局部方法。
static async Task Main(string[] args)
{async Task Execute(CancellationToken token){await Task.Delay(3000, token);Console.WriteLine("Executed");} CancellationTokenSource cts = new CancellationTokenSource(); _ = Execute(cts.Token);// 手动取消任务cts.Cancel(); Console.ReadKey();
}
定时取消任务
创建 CancellationTokenSource 的时候,可以传入时间(毫秒或者Timespan), 通过它我们可以在等待一段时间后,自动取消任务。
CancellationTokenSource cts = new CancellationTokenSource(1000); _ = Execute(cts.Token); Console.ReadKey();
我们也可以调用 cts.CancelAfter(1000), 它会在1s后取消任务。
cts.CancelAfter(1000);
CancellationToken 注册回调
我们可以调用 Register()方法,注册Token取消的回调,参数需要传入 Action 委托。
CancellationTokenSource cts = new CancellationTokenSource(1000);cts.Token.Register(() => Console.WriteLine("任务已取消!"));// 开始异步任务
_ = Execute(cts.Token); Console.ReadKey();
Register() 注册回调后,返回一个 CancellationTokenRegistration 对象,同样的,你可以在回调函数执行前,移除注册回调,就像这样:
cts.Token.Register(() => Console.WriteLine("任务已取消!")).Unregister();
在 HttpClient 中使用
同样,你可以在 HttpClient 中使用传入 CancellationToken (或者使用HttpClient的Timeout属性),超时后,它会抛出一个 TaskCanceledException 的异常:
CancellationTokenSource cts = new CancellationTokenSource(10); _ = await new HttpClient().GetAsync("https://www.youtube.com/",cts.Token); Console.ReadKey();
在 WebAPI中使用
我创建了一个 WebAPI 项目,其中的控制器代码如下,等待了5s,然后进行输出信息。
[HttpGet]
public async Task<IActionResult> Index()
{await Task.Delay(5000);Console.WriteLine("Executed");return Ok();
}
启动项目后,我们在浏览器页面上访问接口,在第一次访问接口等待响应时,我刷新一次了页面,现在程序的输出信息如下:
说明前台页面刷新后,后台并没有做取消操作,执行了两次!
我们可以把程序改成这样,传入 CancellationToken
[HttpGet]
public async Task<IActionResult> Index(CancellationToken token)
{await Task.Delay(5000,token);Console.WriteLine("Executed");return Ok();
}
现在在浏览器访问页面,同样的,第一次还未返回是,我们刷新一次页面,程序输出如下:
只有一次输出,第一次请求抛出了一次 TaskCanceledException 异常,没有继续执行后边的逻辑,当然你可以捕获这个异常,返回更友好的提示!
欢迎扫码关注我们的公众号 【全球技术精选】,专注国外优秀博客的翻译和开源项目分享。
在C#中使用 CancellationToken 处理异步任务相关推荐
- python asyncio教程_python中使用asyncio实现异步IO实例分析
1.说明 Python实现异步IO非常简单,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接 ...
- 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程 | 文末赠书...
正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...
- 操作系统中的同步和异步
操作系统中同步.异步性概念 首先我们从操作系统的发展中学习什么是异步性.在操作系统发展的初期阶段,CPU处理的是作业,而且是单道批处理.什么意思呢?就是一个作业从提交到结束,程序员都不能干预,此时整台 ...
- 异步通信在生活中的例子_聊聊工作中经常遇到的“异步”,你掌握了多少
在我们编程的时候,经常会遇到一个概念--异步,诸如异步通信,异步线程,异步代码,异步调用,异步编程等等,那么 什么是异步呢? 为什么要异步? 异步的典型场景是什么? 如何使用异步呢? ...... 异 ...
- React开发中使用fetch进行异步请求
React开发中使用fetch进行异步请求 最新的Web API接口中提供了一个全局fetch方法,从而以一种更为简单.合理的方式来支持跨网络异步获取资源. 这种功能以前是使用 XMLHttpRequ ...
- V8 中更快的异步函数和 promises
原文作者:Maya Lekova and Benedikt Meurer 译者:UC 国际研发 Jothy 写在最前:欢迎你来到"UC国际技术"公众号,我们将为大家提供与客户端.服 ...
- Spring中解决事务以及异步注解失效
Spring中解决事务以及异步注解失效 一.重现@Transaction失效的场景 有如下业务场景,新增订单后,自动发送短信,下面的代码在同一个类中: @Transaction public void ...
- 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程
正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...
- 小程序怎么处理轮训ajax,微信小程序中使用Promise进行异步流程处理的实例详解...
微信小程序中使用Promise进行异步流程处理的实例详解 我们知道,JavaScript是单进程执行的,同步操作会对程序的执行进行阻塞处理.比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间( ...
最新文章
- 【整理】Linux驱动中,probe函数何时被调用
- python爬取百度图片(用于深度学习中数据集的收集)
- nginx代理转发_学了三年的性能调优,你还不懂Nginx?怎么跳槽涨薪
- html桌面图标样式,如何更改图标样式,换桌面图标的方法
- 傅里叶变换公式_理解1维傅里叶变换
- pyhon量化数据处理小细节3---日期格式转换
- shapefile导入oracle,shp2sdo.exe用法:shpfile导入OracleSpatial
- ipv6的127位掩码如何表示_子网掩码为255.255.255.0代表的意思是什么?
- VMware虚拟机更换根用户( su: Authentication failure问题)
- serialVersionUID作用
- android屏幕适配无效_Android 屏幕适配终结者
- Lottie动画概述,文末有彩蛋
- 三维激光雷达点云拼接
- Android 应用内部打开PDF文件
- 缩放图片至固定大小,尺寸不足以0填充
- web页超过2G以上大视频分片秒传方案
- android usb micro,朝夕相伴不知芳名? 来补补USB接口知识
- matlab寻找频谱峰值,matlab – 从数据中获取FFT峰值
- 【深度学习】损失函数详解
- 信创培训第一课:linux操作系统基础