C# 取消一个不带CancellationToken的任务?

        在异步函数中,一般使用CancellationToken来控制函数的执行。这个Token需要作为参数传递到异步函数中:

public staic Task<T> DoAsync(CancellationToken token)
{...
}

        那么如果一个异步函数没有这个Token参数,如何取消呢?

        之前看到一个博客:How to Cancel a Non-Cancellable Task in C#


1.构建取消异步函数的扩展方法

        先上代码:

    public static class TaskExtensions{public static async Task<T> WithCancellation<T> (this Task<T> task,CancellationToken cancellationToken){var tcs=new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);using (cancellationToken.Register(state =>{((TaskCompletionSource<object>)state!).TrySetResult(null!);}, tcs)){var resultTask = await Task.WhenAny(task, tcs.Task);if(resultTask==tcs.Task){throw new OperationCanceledException(cancellationToken);}return await task;}}}

        显然这是一个扩展方法,旨在为Task<T>类型扩展一个名叫WithCancellation函数。这个函数会有一个CancellationToken,但这个Token不是传递给任务参数task(也就是我们要取消的函数)的,而是用于外部控制。

        代码中首先构建了一个异步任务,利用TaskCompletionSource<T>,可以构建一个用于控制原任务的异步任务,这里的TaskCompletionSource不多解释了,可以参考博客:here。然后通过传入的Token注册一个回调函数,回调函数传入的参数就是刚刚创立的TaskCompletionSource<T>对象,回调函数会调用成员函数TrySetResult()给任务赋值。而回调函数的执行则是在Token被取消时触发。

2. 测试

        然后我们使用这个扩展方法构建实例:

 internal class CancelTaskWithoutCancellationToken{private static readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();public static async Task Test(){try{var result = await Task.Run(async () =>{await Task.Delay(TimeSpan.FromSeconds(5));Console.WriteLine("操作完成");await Task.Delay(300);Console.WriteLine("还继续吗?");return 7;}).WithCancellation(cancellationTokenSource.Token);Console.WriteLine(result.ToString());}catch (Exception ex){Console.WriteLine(ex.Message);Console.WriteLine("任务取消了");}finally{cancellationTokenSource.Dispose();}}public static void Cancel(){cancellationTokenSource?.Cancel();}}

测试代码:

var t1=CancelTaskWithoutCancellationToken.Test();
var t2 = Task.Run(() =>
{Thread.Sleep(1000);CancelTaskWithoutCancellationToken.Cancel();
});
await Task.WhenAll(t1, t2);

运行结果如下:

好像结果很符合预期。

假设测试代码后面还有一些任务要运行,也就是主线程没那么快结束呢?让我们在测试代码后面加一行:

var t1=CancelTaskWithoutCancellationToken.Test();
var t2 = Task.Run(() =>
{Thread.Sleep(1000);CancelTaskWithoutCancellationToken.Cancel();
});
await Task.WhenAll(t1, t2);
Console.WriteLine("----------------------");
Console.ReadLine();

运行结果:

        Oh No,原来的任务还是执行了,说明没能阻止那个任务继续运行,所以原博客说取消一个不能被取消的任务(non-cancelable)是错的,开工没有回头箭。但是从前面的例子,我们可以取消等待那个任务。

        实际上博主在另外一篇博客找到了关于这个问题的说明:

 How do I cancel non-cancelable async operations?

        博主在最后总结:

So, can you cancel non-cancelable operations? No.  Can you cancel waits on non-cancelable operations?  Sure… just be very careful when you do.

        所以,如果想能随时取消一个Task,最稳妥的办法还是将Token作为参数传递进去

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/109615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你们看吧,一看一个不吱声

本来能及时返回&#xff0c;就是无限嵌套 public Result<JSONObject> schedulerClusterSendNotes() {//执行获取集群ID的逻辑//获取集群Result<List<Map>> result bigdataCommonFegin.selectClusterList();if (null ! result && null ! result.get…

TODO Vue typescript forEach的bug,需要再核實

forEach 一個string[]&#xff0c;只有最後一個匹配條件有效&#xff0c;其它條件無效。 所以&#xff0c;只能替換成普通的for循環。 console.log(taskList)// for (const _task of taskList.value) {// if (_task invoiceSendEmail) {// form.value.invoiceSendEmail…

Hadoop3教程(十五):MapReduce中的Combiner

文章目录 &#xff08;103&#xff09;Combiner概述什么是CombinerCombiner有什么用处Combiner有什么特点如何自定义Combiner &#xff08;104&#xff09;Combiner合并案例实操如何从日志里查看Combiner如果不存在Reduce阶段&#xff0c;会发生什么自定义Combiner的两种方式 参…

【SA8295P 源码分析 (二)】68 - Android 侧用户层 输入子系统获取 /dev/input/event0 节点数据 代码流程分析

【SA8295P 源码分析】68 - Android 侧用户层 输入子系统获取 /dev/input/event0 节点数据 代码流程分析 一、EventHub.cpp 监听 /dev/input/event0 节点流程二、EventHub.cpp 读取 /dev/input/event0 节点数据流程系列文章汇总见:《【SA8295P 源码分析 (二)】Display 模块 文章…

【非root用户、CentOS系统】中使用源码安装gcc/g++的教程

1.引言 系统&#xff1a;CentOS-7.9 显卡驱动版本&#xff1a;460 CUDA Version: 11.2 &#x1f33c;基于本地环境选择安装gcc-10.1.0 &#x1f449; gcc下载网址 2.安装说明 下载好对应的gcc的安装包并解压&#xff1a; 打开gcc-10.1.0/contrib/download_prerequisites&#…

Huffman算法

介绍 求解最优二叉树问题通常使用动态规划算法中的一种称为"Huffman算法"或者"Huffman编码"。 Huffman算法的基本思想&#xff1a; 根据节点的频率或者权重构建一棵最优二叉树。最小频率的节点会被放置在树的底部&#xff0c;而较大频率的节点则放置在较…

关于gt_sampling的理解

pcdet/datasets/augmentor/data_augmentor.py def gt_sampling(self, configNone):db_sampler database_sampler.DataBaseSampler(root_pathself.root_path,sampler_cfgconfig,class_namesself.class_names,loggerself.logger)return db_sampler此函数指向DataBaseSampler类&a…

0基础学习VR全景平台篇第109篇:认识拼接软件PTGui Pro

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01;今天给大家讲解我们全景后期拼接软件PTgui pro&#xff0c;下面我们开始吧&#xff01; &#xff08;PTgui pro软件课程大纲&#xff09; 1.PTGui这个软件是什么 发明人 &#xf…

【网络编程】从网络编程、TCP/IP开始到BIO、NIO入门知识(未完待续...)

目录 前言前置知识一、计算机网络体系结构二、TCP/IP协议族2.1 简介*2.2 TCP/IP网络传输中的数据2.3 地址和端口号2.4 小总结 三、TCP/UDP特性3.1 TCP特性TCP 3次握手TCP 4次挥手TCP头部结构体 3.2 UDP特性 四、总结 课程内容一、网络通信编程基础知识1.1 什么是Socket1.2 长连…

【15】基础知识:React扩展知识

一、setState 1. setState 更新状态的 2 种写法 对象式的 setState 语法&#xff1a;setState(stateChange, [callback]) &#xff08;1&#xff09;stateChange 为状态改变对象&#xff08;该对象可以体现出状态的更改&#xff09; &#xff08;2&#xff09;callback 是…

Python之旅----判断语句

布尔类型和比较运算符 布尔类型 布尔类型的定义 布尔类型的字面量&#xff1a; True 表示真&#xff08;是、肯定&#xff09; False 表示假 &#xff08;否、否定&#xff09; 也就是布尔类型进行判断&#xff0c;只会有2个结果&#xff1a;是或否 定义变量存储布尔类型…

天猫店铺商品评论数据采集,天猫商品评论数据接口,天猫API接口

天猫店铺商品评论数据接口可以获取到商品ID&#xff0c;商品标题&#xff0c;商品优惠券&#xff0c;商品到手价&#xff0c;商品价格&#xff0c;商品优惠价&#xff0c;商品sku属性&#xff0c;商品图片&#xff0c;商品视频&#xff0c;商品sku属性图片&#xff0c;商品属性…

【esp32】arduino-数码管

一、数码管类型 按发光二极管单元连接方式分为共阳型数码管和共阴型数码管&#xff0c; 区分:1、可通过查看数码管引脚类型 2、观察数码管点亮状态 3、查询数码管规格表 二、共阳型数码管 是指将所有发光二极管的阳极接到一起形成公共阳极&#xff08;COM)的数码管 三、共…

Chrome跨域访问网络请求Cookies丢失的解决办法

为了保障网络安全,Chrome对跨域访问有一定的限制。一般分为三级: cookies带有“SameSite=Strict”时,只允许访问同一个域名下的网络请求;cookies带有“SameSite=Lax”时,允许访问同一个域名下的网络请求和同一个根域名下的网络请求;cookies带有“SameSite=None”时,允许…

ant中的environment属性

在ant的配置文件中&#xff0c;可以设置属性environment的值&#xff0c;设置的这个值就作为访问环境变量的前缀。例如声明了environment“env”&#xff0c;那么就可以通过env.<环境变量名称>来访问环境变量。 例如创建了一个Java工程&#xff0c;在工程目录下有一个bu…

HCIA --- VLAN实验配置

一、各交换机上配置&#xff1a; 1、各交换机上创建VLAN 2、交换机上的各个接口划分到对应的VLAN中 3、将与交换机、路由器相连的接口创建trunk干道 SW1&#xff1a; [sw1]vlan batch 2 to 3 批量创建VLAN2-3 [sw1]interface Ethernet0/0/1 单独将某个接口划分到对应…

信息保卫战:揭秘迅软DSE护航企业免受泄密之害

随着网络技术的发展&#xff0c;通过网络应用如网盘、网页、邮件、即时通讯工具传输分享文件变得越来越多&#xff0c;这些工具传输速度快&#xff0c;能够将大容量的文档快速传送给他人&#xff0c;在工作中受到许多人的青睐。 然而由这些传输工具引发的泄密事件也不断增多&am…

【农业生产系统模型】基于R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

SQL Server 修改、删除表中数据

SQL Server 修改、删除表中数据 修改 SQL Server修改表中数据的关键字是update&#xff08;更新;使现代化;向…提供最新信息;给…增加最新信息&#xff09; 修改表中信息 语法 update 表名 set 字段1值1&#xff0c;字段值2 where 条件1 and 条件2给表中所有人加工资&…

前后端交互—Ajax基础

Ajax 代码下载 URL地址 URL(全称是UniformResourceLocator)中文叫统一资源定位符&#xff0c;用于标识互联网上每个资源的唯一存放位置。 浏览器只有通过URL地址&#xff0c;才能正确定位资源的存放位置&#xff0c;从而成功访问到对应的资源。常见的URL举例: http://www.ba…