C# CancellationToken 终止操作

需要在异步操作中提供终止功能时,最常用的方法是使用 CancellationToken。这个工具可以让你在需要时优雅地取消异步操作,而不是强制终止线程。

.NET 中不建议直接终止线程,因为这可能导致资源泄露和数据不一致等问题。强制终止线程可能会中断一个正在执行的操作,甚至可能使应用程序处于未定义的状态。

1. 什么是 CancellationToken

CancellationToken 是 .NET 提供的一个结构,用于处理异步任务的取消。它允许你在长时间运行的操作中检查用户是否请求取消,从而保证程序的响应性。

2. 使用 CancellationToken 的基本步骤

以下是使用 CancellationToken 的关键步骤,这些步骤在示例代码中都有体现:

步骤 1:创建 CancellationTokenSource

首先,创建一个 CancellationTokenSource 实例。这个实例提供了一个 CancellationToken,可以将其传递给异步方法。

static CancellationTokenSource cts = new CancellationTokenSource();

步骤 2:获取 CancellationToken

通过 CancellationTokenSource 获取一个 CancellationToken,这个令牌将用于检查取消请求。

var token = cts.Token;

步骤 3:传递 CancellationToken 给异步方法

在定义的异步方法中,接受 CancellationToken 参数,并在适当的位置检查它的状态。

static async Task LongRunningOperation(CancellationToken token)
{
    for (int i = 0; i < 100; i++)
    {
        token.ThrowIfCancellationRequested(); // 检查是否请求取消
        
        // 模拟耗时操作
        Console.WriteLine($"处理第 {i + 1} 项...");
        await Task.Delay(100); // 代替耗时的操作
    }
}

在循环中,我们调用 token.ThrowIfCancellationRequested() 方法。如果调用此方法时取消请求已经发出,则会抛出 OperationCanceledException,从而允许我们在主方法中捕获并处理。

 

步骤 4:请求取消

在用户按下某个键(例如 'c' 键)时,你可以请求取消操作。这通过调用 CancellationTokenSource.Cancel 方法来实现。

if (Console.ReadKey().KeyChar == 'c')
{
    cts.Cancel(); // 请求取消
}

步骤 5:处理取消

在主方法中,通过 try-catch 块捕获 OperationCanceledException,以便在操作被取消时进行适当处理。

try
{
    await processingTask; // 等待任务完成
}
catch (OperationCanceledException)
{
    Console.WriteLine("操作已被取消。");
}

完整代码

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static CancellationTokenSource cts = new CancellationTokenSource();

    static async Task Main(string[] args)
    {
        Console.WriteLine("按下任意键开始长时间操作...");
        Console.ReadKey();

        var processingTask = LongRunningOperation(cts.Token);

        Console.WriteLine("按下 'c' 键取消操作...");
        if (Console.ReadKey().KeyChar == 'c')
        {
            cts.Cancel(); // 请求取消
        }

        try
        {
            await processingTask; // 等待任务完成
            Console.WriteLine("操作完成。");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("操作已被取消。");
        }
        finally
        {
            cts.Dispose();
        }
    }

    static async Task LongRunningOperation(CancellationToken token)
    {
        for (int i = 0; i < 100; i++)
        {
            token.ThrowIfCancellationRequested(); // 检查是否请求取消
            
            // 模拟耗时操作
            Console.WriteLine($"处理第 {i + 1} 项...");
            await Task.Delay(100); // 代替耗时的操作
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ubuntu-22.04】ubuntu-22.04搭建openwrt-23.05编译环境操作说明

ubuntu-22.04镜像下载 Index of /releases/22.04.1 安装ubuntu系统 安装openwrt-23.05依赖包 sudo apt update sudo apt install build-essential clang flex bison g++ gawk \ gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev \ python3-distutils pyth…

html+css网页设计马林旅行社移动端4个页面

htmlcss网页设计马林旅行社移动端4个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#…

【算法】位运算合集

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 零&#xff1a;位运算基础公式 零&#xff1a;五道基础题 1&#xff1a;位1的个数 2&#xff1a;比…

Android 硬件抽象层(HAL)全解析:智能设备硬件协同揭秘

在Android硬件抽象层&#xff08;HAL&#xff09;开发中&#xff0c;需要掌握许多底层技术&#xff0c;并熟悉如何将硬件驱动与Android系统的上层应用接口相集成。以下是HAL开发中需要掌握的核心技术和一些示例代码&#xff0c;以帮助理解其实现原理&#xff1a; 1. C/C编程和…

Linux如何将文件或目录打成rpm包?-- rpmbuild打包详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

推荐学习笔记:矩阵补充和矩阵分解

参考&#xff1a; 召回 fun-rec/docs/ch02/ch2.1/ch2.1.1/mf.md at master datawhalechina/fun-rec GitHub 业务 隐语义模型与矩阵分解 协同过滤算法的特点&#xff1a; 协同过滤算法的特点就是完全没有利用到物品本身或者是用户自身的属性&#xff0c; 仅仅利用了用户与…

java引用第三方jar包,打包全流程

前言&#xff1a; 本文是使用maven引入第三方jar包&#xff0c;通过mvn命令打包。 以下为引入第三方jar包&#xff0c;打包进项目jar中的全流程步骤。 1、引入第三方jar包 1、放置路径 一般来说&#xff0c;放到项目(子项目)的resources的lib目录下。 2、pom引入 如图所示…

【webApp之h5端实战】首页评分组件的原生实现

关于评分组件,我们经常在现代前端框架中用到,UI美观效果丰富,使用体验是非常不错的。现在自己动手使用原生js封装下评分组件,可以用在自己的项目中。 组件实现原理 点击的❤左侧包括自己都是高亮的样式,右侧都是灰色的样式,这样就能把组件的状态区分开了。右边再加上辅…

基于Java Springboot旅游攻略APP且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…

ScratchLLMStepByStep:一步一步构建大语言模型教程

前言 在学习大语言模型的时候&#xff0c;总会遇到各种各样的名词&#xff0c;像自注意力、多头、因果、自回归、掩码、残差连接、归一化等等。这些名词会让学习者听的云里雾里&#xff0c;觉得门槛太高而放弃。 本教程将会带你从零开始&#xff0c;一步一步的去构建每一个组…

[MacOS] [kubernetes] MacOS玩转虚拟化最佳实践

❓ 为什么不在MacOS本机安装呢&#xff1f;因为M系列芯片是Arm架构&#xff0c;与生产环境或者在本地调试时候&#xff0c;安装虚拟镜像和X86不同&#xff0c;造成不必要的切换环境的额外成本&#xff0c;所以在虚拟化的x86调试 步骤 & 详情 一: 安装OrbStack & 并配置…

MySQL的用户管理和密码管理

用户的密码管理 给用户改密码 初始化mysql后设置初始密码 mysqladmin -uroot password wzy666 改变已有密码 mysqladmin -uroot -pwzy666 password wzy999 SQL语句改&#xff0c;前提是已经进入数据库 alter user rootlocalhost identified by 123456; # 利用数据库服务…

SQLite:DDL(数据定义语言)的基本用法

SQLite&#xff1a;DDL&#xff08;数据定义语言&#xff09;的基本用法 1 主要内容说明2 相关内容说明2.1 创建表格&#xff08;create table&#xff09;2.1.1 SQLite常见的数据类型2.1.1.1 integer&#xff08;整型&#xff09;2.1.1.2 text&#xff08;文本型&#xff09;2…

STM32--基于STM32的智能家居设计与实现

本文详细介绍基于STM32F103C8T6的智能家居设计与实现&#xff0c;详细设计资料见文末链接 一、功能模块介绍 智能家居系统系统图如下所示&#xff0c;主要包括温湿度传感器、OLED液晶显示&#xff0c;WIFI物联网模块、人体红外预警模块、烟雾传感器模块、蜂鸣器模块 &#…

基于Java Springboot校园导航微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse微信开发…

在 uniapp 项目中使用 Iconify 字体图标库

本文示例在 uniapp 项目中对 Iconify 字体图标库的安装和使用&#xff08;Iconify 字体图标库是一个免费开源的图标库&#xff0c;它拥有超过20万个开源矢量图标。&#xff09; 注&#xff1a;本文示例使用的是其 vue3 版本 安装 npm install --save-dev iconify/vue 注&am…

WPF+LibVLC开发播放器-LibVLC播放控制

接上一篇&#xff1a; LibVLC在C#中的使用 实现LibVLC播放器播放控制 界面 界面上添加一个Button按钮用于控制播放 <ButtonGrid.Row"1"Width"88"Height"24"Margin"10,0,0,0"HorizontalAlignment"Left"VerticalAlignme…

ffmpeg安装及配置简单教程

这是ffmpeg官方网站&#xff1a;https://ffmpeg.org/ 这是ffmpeg提供了其他版本的网站&#xff1a;Builds - CODEX FFMPEG gyan.dev 这是ffmpeg提供了提前编译好的可执行文件的github托管网站&#xff1a; https://github.com/BtbN/FFmpeg-Builds/releases 一般windows版本…

Qt-界面优化QSS

QSS介绍 先说下CSS&#xff1a; 在⽹⻚前端开发领域中, CSS 是⼀个⾄关重要的部分. 描述了⼀个⽹⻚的 "样式". 从⽽起到对⽹⻚美化的作⽤。 Qt 仿照 CSS 的模式, 引⼊了 QSS, 来对 Qt 中的控件做出样式上的设定 。 CSS的功能很强大&#xff0c;QSS要逊色一些&#…

后端-一对一的数据封装的两种写法对比

方式一特点&#xff1a;上面的普通封装可以删掉&#xff0c;也可以留着。 注意⚠️&#xff1a;下面的特殊封装的property的值是属性.字段。&#xff08;category.id...) column是sql重命名之后的字段&#xff0c;如果没有重命名是数据库中的值。 方式二特点&#xff1a;上面的…