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.rhkb.cn/news/162094.html

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

相关文章

Dasviewer浏览器里显示模型裁剪不成功,输出无数据是什么原因?

答&#xff1a;Metadata文件需要先放在Terraosgb文件夹瓦块再试试 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览操作。#DasViewer##…

JAVA基础(JAVA SE)学习笔记(三)流程控制语句

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 JAVA基础&#xff08;JAVA SE&#xff09;学习笔记&#xff08;一&#xff09;JAVA学习路线、行业了解、…

git 使用

参考 https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7%E5%8F%96-Git-%E4%BB%93%E5%BA%93 文件的状态变化周期 文章目录 git 基础检查当前文件状态、查看已暂存和未暂存的修改暂存前后的变化跟踪新文件提交更新移除文件移动文件、重命名操作查看提交历史撤消…

企业c#语言源代码防泄密解决方案

在当今数字化时代&#xff0c;企业的核心业务往往依赖于软件应用程序。为了保护企业的知识产权和敏感信息&#xff0c;源代码的保密至关重要。对于制造类企业尤其是智能制造业来讲&#xff0c;最近几年是高速发展的时期&#xff0c;很多公司在做工厂流水线设备时&#xff0c;就…

Redis分布式锁

目录 ​编辑Redis实现全局唯一Id 测试类 关于countdownlatch 添加优惠卷 实现秒杀下单 库存超卖问题分析 优惠券秒杀-一人一单 ​编辑 分布式锁 基本原理和实现方式对比 Redis分布式锁的实现核心思路 实现分布式锁版本一 Redis分布式锁误删情况说明 解决Redis分布式…

安防视频监控平台EasyCVR出现视频流播放卡顿情况,如何优化?

视频集中存储/云存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。AI智能/大数据视频分析EasyCVR平台已经广泛应用在工地、工厂、园区、楼…

超细致的性能测试流程,你get了吗?

性能测试&#xff1a;利用工具模拟大量用户操作&#xff0c;验证系统承受的负载情况。 性能测试的目的&#xff1a;找到潜在的性能问题或瓶颈&#xff0c;分析并解决&#xff1b;找出性能变化趋势&#xff0c;为后续扩展系统提供参考。测试监控&#xff1a;基准测试、配置测试…

【嵌入式开发问答】不是普通的嵌入式八股

1. 进程、线程、堆栈、溢出 【问&#xff1a;】 进程的堆栈的物理内存是什么时候分配的&#xff1f; 堆栈的大小限制是多大&#xff1f;这个限制可以调整吗&#xff1f; 当堆栈发生溢出后应用程序会发生什么&#xff1f; 【答&#xff1a;】

Kafka消费者使用案例

本文代码链接:https://download.csdn.net/download/shangjg03/88422633 1.消费者和消费者群组 在 Kafka 中,消费者通常是消费者群组的一部分,多个消费者群组共同读取同一个主题时,彼此之间互不影响。Kafka 之所以要引入消费者群组这个概念是因为 Kafka 消费者经常会做一些高…

小谈设计模式(26)—中介者模式

小谈设计模式&#xff08;26&#xff09;—中介者模式 专栏介绍专栏地址专栏介绍 中介者模式分析角色分析抽象中介者&#xff08;Mediator&#xff09;具体中介者&#xff08;ConcreteMediator&#xff09;抽象同事类&#xff08;Colleague&#xff09;具体同事类&#xff08;C…

代码覆盖率统计Super-jacoco在公司级容器化项目中的具体应用方案

目录 一、介绍 二、自己在本地搭建Super-jacoco服务 2.1 准备工作 2.2 部署super jacoco服务 1、下载super jacoco 项目 2、初始化数据库 3、配置application.properties 4、编译super jacoco项目 5、部署 super jacoco 服务 2.3 启动被测项目 2.4、代码覆盖率收集 2…

苹果官网上架新款Apple Pencil(USB-C)

昨天晚上苹果在其官网发布了新款Apple Pencil手写笔&#xff0c;苹果将该产品命名为 Apple Pencil&#xff08;USB-C&#xff09;&#xff0c;新款Apple Pencil采用了全新的USB-C接口&#xff0c;支持USB-C充电&#xff0c;兼容所有配备USB-C接口的iPad机型&#xff0c;售价为6…

【排序算法】详解冒泡排序及其多种优化稳定性分析

文章目录 算法原理细节分析优化1优化2算法复杂度分析稳定性分析总结 算法原理 冒泡排序(Bubble Sort) 就是从序列中的第一个元素开始&#xff0c;依次对相邻的两个元素进行比较&#xff0c;如果前一个元素大于后一个元素则交换它们的位置。如果前一个元素小于或等于后一个元素…

从入门到进阶 之 ElasticSearch 文档、分词器 进阶篇

&#x1f339; 以上分享 ElasticSearch 文档、分词器 进阶篇&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏&#…

修炼k8s+flink+hdfs+dlink(五:安装dockers,cri-docker,harbor仓库,k8s)

一&#xff1a;安装docker。&#xff08;所有服务器都要安装&#xff09; 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2添加软件源信息 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/cent…

27. 移除元素

27. 移除元素 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;__27移除元素__27移除元素__双指针优化 原题链接&#xff1a; 27. 移除元素 https://leetcode.cn/problems/remove-element/description/ 完成情况&#xff1a; 解题思路&a…

Python使用openpyxl读取excel图片

使用openpyxl读取excel中图片&#xff0c;并保存到本地. 需要的包。 from openpyxl import load_workbook from PIL import Image import cv2 import numpy as np具体实现 先把openpyxl读取的图片转换为Image对象&#xff0c;再将Image对象转换为numpy array&#xff0c;num…

DNS压测工具-dnsperf的安装和使用(centos)

系统调优 系统调优脚本&#xff0c;保存为sh文件&#xff0c;chmod提权后执行即可 #!/bin/sh #系统全局允许分配的最大文件句柄数&#xff1a; sysctl -w fs.file-max2097152 sysctl -w fs.nr_open2097152 echo 2097152 > /proc/sys/fs/nr_open #允许当前会话 / 进程打开文…

JAVA基础(JAVA SE)学习笔记(二)变量与运算符

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 第一阶段&#xff1a;Java基本语法 1. Java 语言概述 JAVA基础&#xff08;JAVA SE&#xff09;学习…

抖音同城榜上榜策略

随着抖音的普及&#xff0c;越来越多的人开始使用抖音来展示自己的才华、记录生活或者做推广。但是&#xff0c;如何让自己的短视频在抖音同城榜上榜&#xff0c;成为本地热门话题呢&#xff1f;下面&#xff0c;我将分享一些实用的策略&#xff0c;帮助您实现这一目标。 抖音同…