首页 > 编程语言 >C#中使用 CancellationToken 取消异步任务

C#中使用 CancellationToken 取消异步任务

时间:2023-01-25 23:23:04浏览次数:44  
标签:CancellationToken 异步 Console cts C# CancellationTokenSource 取消 Token

.NET 提供了一个类方便用来发出操作取消的信号,这个类就是CancellationToken,它的好处在于它可以在任意数量的线程之间、线程池任务之间、Task之间传递信号,并且所需的代码很简单。通常用于下载超时中断、用户取消任务等情况。

CancellationToken 通常搭配 CancellationTokenSource 使用,后者是前者的一个管理类,使用 CancellationTokenSource 的 Token 属性,可以获取CancellationToken,并控制信号的发送。这两个类都属于命名空间 System.Threading

在异步编程中,只需将 Token 作为一个参数传入异步方法中。在异步方法外便能通过 CancellationTokenSource.Cancel 方法发出取消信号或者 CancelAfter 方法在一段时间后发出取消信号,这会改变 Token 的 isCancellationRequested 属性。在异步方法内,通过这个属性获取取消信号,并作出对应的处理操作。

一、定时取消任务

代码示例:

 1 using System;
 2 using System.Threading.Tasks;
 3 using System.Threading;
 4 using System.Net.Http;
 5 
 6 namespace CancellationTokenTest
 7 {
 8     class Program
 9     {
10         static async Task Main(string[] args)
11         {
12             CancellationTokenSource cts = new CancellationTokenSource();
13             //cts.Cancel() //立即发出取消信号
14             //3秒后发出取消信号,模拟取消行为
15             cts.CancelAfter(3000);
16             Console.WriteLine("下载开始");
17             await DownloadAsync(cts.Token);
18             Console.ReadKey();
19         }
20 
21         static async Task DownloadAsync(CancellationToken ct)
22         {
23             using (HttpClient client = new HttpClient())
24             {
25                 //模拟一个比较耗时的下载的过程
26                 for (int i = 0; i < 1000; i++)
27                 {
28                     string s = await client.GetStringAsync("https://www.baidu.com");
29                     Console.WriteLine(s);
30 
31                     //ct.ThrowIfCancellationRequested();//直接抛出异常
32                     //判断是否需要取消,并自行处理
33                     if (ct.IsCancellationRequested)
34                     {
35                         Console.WriteLine("下载取消");
36                         break;
37                     }
38                 }
39                 
40             }
41         }
42 
43     }
44 }

3秒之后,任务将自动取消。

二、手动取消任务

手动调用 cts.Cancel() 来取消任务

 1  
 2 static async Task Main(string[] args)
 3 {
 4     async Task Execute(CancellationToken token)
 5     {
 6         await Task.Delay(3000, token);
 7         Console.WriteLine("Executed");
 8     } 
 9  
10     CancellationTokenSource cts = new CancellationTokenSource();  
11  
12     _ = Execute(cts.Token);
13  
14     // 手动取消任务
15     cts.Cancel();  
16  
17     Console.ReadKey();
18 }

三、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();

 

标签:CancellationToken,异步,Console,cts,C#,CancellationTokenSource,取消,Token
From: https://www.cnblogs.com/handsomeziff/p/17067435.html

相关文章

  • Cesium计算三角形面积(十)
    functiontriangleArea(p0,p1,p2){//利用subtract计算出两个向量letv0=Cesium.Cartesian3.subtract(p0,p1,newCesium.Cartesian3())......
  • go mod init 之后 vscode报错gopls was not able to find modules in your workspace
    (27条消息)vscode报错packagexxxisnotinGOROOT(path)或者go:toaddmodulerequirementsandsums:gomodtidy_Kpdo的博客-CSDN博客上文是我在网上看了2天2夜,......
  • torch.Tensor.backward()简单使用
    目录前言标量变量的反向传播前言在深度学习中,经常需要对函数求梯度(gradient)。PyTorch提供的autograd包能够根据输入和前向传播过程自动构建计算图,并执行反向传播。本文主......
  • Adobe Color 的替代软件:焰火十二卷
    一、前言AdobeColor是一个配色网站,可以在线生成不同风格的色彩主题,受到设计师的喜爱。然而,AdobeColor服务器在国外,导致连接速度很慢,甚至会连接不上。并且,AdobeColor......
  • Day02 - JavaScripts
    1.javascript介绍JavaScript的定义JavaScript是运行在浏览器端的脚步语言,是由浏览器解释执行的,简称js,它能够让网页和用户有交互功能,增加良好的用户体验效果。......
  • Functions
    BacktoDefinitionsfunction - anamedsequenceofstatementsthatperformsaspecifictaskorusefuloperationparameter - avariablethatreceivesanar......
  • 迁移学习(Deep CORAL)《Deep CORAL: Correlation Alignment for Deep Domain Adaptation
    论文信息论文标题:DeepCORAL:CorrelationAlignmentforDeepDomainAdaptation论文作者:BaochenSun,KateSaenko论文来源:ECCV2016论文地址:download 论文代码:downlo......
  • LeetCode正则表达式匹配(lambda/dp)
    lambda表达式[捕获列表](参数列表)mutable(可选)异常属性->返回类型{//函数体}所谓捕获列表,其实可以理解为参数的一种类型,lambda表达式内部函数体在默认情况下......
  • 解决:“error PRJ0003 : 生成“cmd.exe”时出错”
    昨晚用VS2005刚写好的程序,今天打算修改,不料在编绎时,却出现了错误,错误信息如下:“errorPRJ0003:生成“cmd.exe”时出错”解决方法:在VisualStudio2005中进行如下设置:打......
  • C++零拷贝
    零拷贝就是一种避免CPU将数据从一块存储拷贝到另外一块存储的技术vector的函数emplace_back()它跟push_back()函数一样可以将一个元素插入容器尾部区别在于使用push_b......