在 .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 处理异步任务相关推荐

  1. python asyncio教程_python中使用asyncio实现异步IO实例分析

    1.说明 Python实现异步IO非常简单,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接 ...

  2. 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程 | 文末赠书...

    正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...

  3. 操作系统中的同步和异步

    操作系统中同步.异步性概念 首先我们从操作系统的发展中学习什么是异步性.在操作系统发展的初期阶段,CPU处理的是作业,而且是单道批处理.什么意思呢?就是一个作业从提交到结束,程序员都不能干预,此时整台 ...

  4. 异步通信在生活中的例子_聊聊工作中经常遇到的“异步”,你掌握了多少

    在我们编程的时候,经常会遇到一个概念--异步,诸如异步通信,异步线程,异步代码,异步调用,异步编程等等,那么 什么是异步呢? 为什么要异步? 异步的典型场景是什么? 如何使用异步呢? ...... 异 ...

  5. React开发中使用fetch进行异步请求

    React开发中使用fetch进行异步请求 最新的Web API接口中提供了一个全局fetch方法,从而以一种更为简单.合理的方式来支持跨网络异步获取资源. 这种功能以前是使用 XMLHttpRequ ...

  6. V8 中更快的异步函数和 promises

    原文作者:Maya Lekova and Benedikt Meurer 译者:UC 国际研发 Jothy 写在最前:欢迎你来到"UC国际技术"公众号,我们将为大家提供与客户端.服 ...

  7. Spring中解决事务以及异步注解失效

    Spring中解决事务以及异步注解失效 一.重现@Transaction失效的场景 有如下业务场景,新增订单后,自动发送短信,下面的代码在同一个类中: @Transaction public void ...

  8. 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程

    正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...

  9. 小程序怎么处理轮训ajax,微信小程序中使用Promise进行异步流程处理的实例详解...

    微信小程序中使用Promise进行异步流程处理的实例详解 我们知道,JavaScript是单进程执行的,同步操作会对程序的执行进行阻塞处理.比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间( ...

最新文章

  1. 【整理】Linux驱动中,probe函数何时被调用
  2. python爬取百度图片(用于深度学习中数据集的收集)
  3. nginx代理转发_学了三年的性能调优,你还不懂Nginx?怎么跳槽涨薪
  4. html桌面图标样式,如何更改图标样式,换桌面图标的方法
  5. 傅里叶变换公式_理解1维傅里叶变换
  6. pyhon量化数据处理小细节3---日期格式转换
  7. shapefile导入oracle,shp2sdo.exe用法:shpfile导入OracleSpatial
  8. ipv6的127位掩码如何表示_子网掩码为255.255.255.0代表的意思是什么?
  9. VMware虚拟机更换根用户( su: Authentication failure问题)
  10. serialVersionUID作用
  11. android屏幕适配无效_Android 屏幕适配终结者
  12. Lottie动画概述,文末有彩蛋
  13. 三维激光雷达点云拼接
  14. Android 应用内部打开PDF文件
  15. 缩放图片至固定大小,尺寸不足以0填充
  16. web页超过2G以上大视频分片秒传方案
  17. android usb micro,朝夕相伴不知芳名? 来补补USB接口知识
  18. matlab寻找频谱峰值,matlab – 从数据中获取FFT峰值
  19. 【深度学习】损失函数详解
  20. 信创培训第一课:linux操作系统基础

热门文章

  1. 2018-2019-2 20175235 实验四《Android开发基础》实验报告
  2. vue---day03
  3. EntityFramework6.X 之 Fulent
  4. 【第四周作业】参加项目开发之后的一些体会
  5. 游戏开发Camera之Cinematic Camera-深度
  6. JSP使用JSON传递数据,注意避免中文乱码
  7. 如何衡量两个词的相关度
  8. 如何在Windows 8中更改登录屏幕的颜色
  9. [译] 机器学习可以建模简单的数学函数吗?
  10. Dubbo源码解析之Zookeeper连接