C# Task 包含 await ConfigureAwait CancellationTokenSource
- `Task`
- 以下是 `Task` 类的一些关键特性和用法:
- 以下是一些使用 `Task` 的示例:
- 创建并启动一个任务
- 使用 `await` 等待任务完成
- 处理任务异常
- 使用 `Task<TResult>` 获取结果
- 取消任务
- 总结
- `await`
- 暂停方法执行:
- 非阻塞调用:
- 任务结果获取:
- 异常处理:
- 同步上下文恢复:
- 配置任务继续执行的线程:
- 组合异步操作:
- 简化异步编程:
- 下面是一个使用 `await` 的简单示例:
- `ConfigureAwait`
- 使用场景
- 语法
- 参数
- 示例
- 总结
- `CancellationTokenSource`
- 下面是一个使用 `CancellationTokenSource` 的示例:
- 总结
- 个人理解
- 例子如下
- 运行结果如下
Task
在C#中,Task 是 System.Threading.Tasks 命名空间中的一个类,它代表了异步操作 的执行。Task 类是异步编程模型的核心,它允许开发者编写非阻塞的代码,提高应用程序的响应性和性能。
以下是 Task 类的一些关键特性和用法:
-
表示异步操作:
Task表示一个可能已经完成、正在运行或尚未开始的异步操作。 -
返回值:
Task<TResult>是Task的泛型版本,它表示一个异步操作,该操作将返回一个指定类型的结果。 -
状态跟踪:
Task对象提供了属性来跟踪其状态,如Status、IsCompleted、IsFaulted等。 -
异常处理:如果异步操作中发生异常,
Task对象的Exception属性将包含异常信息。 -
等待完成:可以使用
await关键字或Task.Wait()、Task.Result方法来等待Task完成。 -
取消支持:
Task支持使用CancellationToken来取消操作。 -
连续性:可以使用
ContinueWith方法来安排在任务完成后执行的连续任务。 -
并行执行:
Task可以与其他任务并行执行,使用Task.WhenAll或Task.WhenAny来管理多个任务的完成。
以下是一些使用 Task 的示例:
创建并启动一个任务
// 创建并启动一个任务
Task task = Task.Run(() =>
{Console.WriteLine("Task is running on thread: " + Thread.CurrentThread.ManagedThreadId);
});
// 等待任务完成
task.Wait();
使用 await 等待任务完成
public async Task DoWorkAsync()
{await Task.Run(() => {// 模拟长时间运行的任务Thread.Sleep(1000);Console.WriteLine("Work is done.");});
}
处理任务异常
public async Task DoWorkWithExceptionAsync()
{try{await Task.Run(() => {throw new InvalidOperationException("Something went wrong!");});}catch (Exception ex){Console.WriteLine($"Caught an exception: {ex.Message}");}
}
使用 Task<TResult> 获取结果
public async Task<int> GetResultAsync()
{return await Task.Run(() => {// 模拟计算过程return 42;});
}
取消任务
public async Task CancelTaskAsync(CancellationToken cancellationToken)
{var task = Task.Run(() =>{while (!cancellationToken.IsCancellationRequested){// 模拟长时间运行的任务}}, cancellationToken);await Task.Delay(100); // 模拟一段时间后取消任务cancellationToken.Cancel();await task;
}
总结
Task 类是.NET异步编程的基础,它提供了一种简单而强大的方式来编写和组织异步代码。
await
在 C# 中,await 关键字用于异步编程,它有几个关键作用:
暂停方法执行:
当编译器遇到一个
await表达式时,它会暂停当前async方法的执行,直到被await的任务(Task或Task<T>)完成。
非阻塞调用:
await 允许程序在等待异步操作完成时继续执行其他代码。这意味着程序可以执行其他任务,而不是被阻塞等待异步操作的完成。
任务结果获取:
当 await 一个 Task<T> 时,它返回任务的结果。一旦任务完成,await 表达式的结果就是 Task<T> 的结果。
异常处理:
如果 await 的任务失败并抛出异常,异常会被传播到 await 调用的地方。如果 await 被包含在一个 try 块中,异常可以被捕获和处理。
同步上下文恢复:
await 表达式可以配置为在特定的同步上下文中继续执行(例如,UI 线程)。如果 await 表达式没有指定继续执行的上下文,它将恢复到调用它的原始上下文。
配置任务继续执行的线程:
使用 await 时,可以指定一个 TaskScheduler,来决定任务完成后在哪个线程上继续执行。
组合异步操作:
await 可以与 async 一起使用,创建更复杂的异步工作流,如链式调用多个异步方法。
简化异步编程:
使用 await 和 async 可以大大简化异步代码的编写,使异步代码看起来和同步代码类似,更容易理解和维护。
下面是一个使用 await 的简单示例:
using System;
using System.Threading.Tasks;class Program
{static async Task Main(){int result = await GetNumberAfterDelayAsync();Console.WriteLine(result);}static async Task<int> GetNumberAfterDelayAsync(){await Task.Delay(1000); // 模拟异步操作,延迟1秒return 42; // 返回结果}
}
在这个示例中,Main 方法使用 await 等待 GetNumberAfterDelayAsync 方法完成,并获取它返回的整数结果。await 使得 Main 方法可以非阻塞地等待异步操作的完成。
ConfigureAwait
在C#中,ConfigureAwait 是一个方法,用于配置 await 操作是否继续在原始的同步上下文上执行,或者是否继续在不同的上下文上执行。这通常在异步编程中使用,特别是在使用 Task 和 async 关键字时。
当你调用一个异步方法并使用 await 时,await 会返回一个 Task 或 Task<T> 对象。ConfigureAwait 是 Task 的一个扩展方法,允许你指定是否要捕获当前的同步上下文,并在继续执行异步操作时使用它。
使用场景
通常,当你在 UI 应用程序中使用异步方法时,你可能希望在 UI 线程上继续执行,以更新 UI 元素。默认情况下,await 会尝试捕获当前的同步上下文,并在异步操作完成后返回到这个上下文。但是,如果你在一个没有 UI 线程的上下文中使用 await,或者你希望避免不必要的上下文捕获,你可以使用 ConfigureAwait(false)。
语法
await someTask.ConfigureAwait(false);
参数
false:指示 await 操作不需要捕获当前的同步上下文。这意味着当异步操作完成时,它不会尝试返回到原始的上下文,这可以提高性能,尤其是在没有 UI 线程或不需要 UI 更新的情况下。
true(默认值):指示 await 操作应该捕获当前的同步上下文,并在异步操作完成后返回到这个上下文。这在需要更新 UI 或访问线程绑定对象时非常有用。
示例
public async Task SomeAsyncMethod()
{// 执行一些异步操作await SomeOtherAsyncMethod().ConfigureAwait(false);// 继续执行其他操作,这里不会捕获原始的同步上下文
}
总结
使用 ConfigureAwait(false) 可以提高性能,特别是在高并发的环境下,因为它避免了不必要的上下文切换。然而,你应该谨慎使用它,确保不会因此而违反线程安全或 UI 更新的需求。
CancellationTokenSource
CancellationTokenSource 是C#中的一个类,它提供了一种机制来发出取消请求。这个类与 CancellationToken 类一起使用,允许异步操作被取消。以下是 CancellationTokenSource 的一些关键特性和用法:
-
创建: 你可以创建一个
CancellationTokenSource的实例来开始一个取消操作。 -
取消: 通过调用
CancellationTokenSource的Cancel方法,你可以发出取消请求。 -
传播取消:
CancellationTokenSource可以传播取消请求到所有与之关联的CancellationToken对象。 -
超时: 你可以设置一个超时时间,如果超时时间到了,取消请求会自动发出。
-
链接: 你可以将多个
CancellationTokenSource实例链接在一起,这样任何一个源发出取消请求,都会传播到所有链接的源。
下面是一个使用 CancellationTokenSource 的示例:
using System;
using System.Threading;
using System.Threading.Tasks;public class Program {public static void Main() {// 创建CancellationTokenSourcevar cts = new CancellationTokenSource();// 创建CancellationTokenCancellationToken token = cts.Token;// 启动一个异步任务Task task = Task.Run(() =>DoLongRunningOperation(token), token);// 模拟用户决定取消操作Console.WriteLine("按任意键取消操作...");Console.ReadKey();// 发出取消请求cts.Cancel();try {// 等待任务完成或抛出异常task.Wait();} catch (AggregateException ae) {// 处理取消异常foreach (var e in ae.InnerExceptions) {if (e is OperationCanceledException) {Console.WriteLine("操作已被取消。");}}}}private static void DoLongRunningOperation(CancellationToken cancellationToken) {for (int i = 0; i < 10; i++) {// 检查是否有取消请求cancellationToken.ThrowIfCancellationRequested();// 模拟长时间的工作Thread.Sleep(1000);Console.WriteLine($"执行步骤 {i + 1}");}}
}
总结
在这个示例中,我们创建了一个 CancellationTokenSource 并从它获取了一个 CancellationToken。然后,我们启动了一个异步任务 DoLongRunningOperation,并将 CancellationToken 传递给它。当用户按下任意键时,我们调用 Cancel 方法来发出取消请求。如果任务被取消,DoLongRunningOperation 方法中的 ThrowIfCancellationRequested 将抛出 OperationCanceledException 异常,我们捕获这个异常并处理它。
个人理解
对于一个aysnc修饰的方法,没有什么特殊的,调用也是正常的按顺序执行,但是,一旦你使用了await
就会出现这样的事情:
- 首先,由于必须在有
aysnc修饰的方法中使用await, - 于是就说明的
async的作用——将方法包装成状态机, - 所以在执行到
await时:对于主线程来说,整个状态机(async修饰的方法)都会被挂起,然后这个方法会到其他线程执行,主线程继续执行该方法之后的语句,直到await后面的语句执行完毕, - 最后方法从被挂起的状态回归
例子如下
using System;
using System.Threading;
using System.Threading.Tasks;public class Program {public async static Task Main() {var cts = new CancellationTokenSource();CancellationToken token = cts.Token;try {DoLongRunningOperation(token);Console.WriteLine("Main Thread:" + Environment.CurrentManagedThreadId);Thread.Sleep(500);cts.Cancel();} catch (TaskCanceledException ee) {Console.WriteLine(ee.Message);}Console.ReadKey();}private async static Task DoLongRunningOperation(CancellationToken cancellationToken) {int i = 1;while (!cancellationToken.IsCancellationRequested) {Console.WriteLine("DoLo Thread:" + Environment.CurrentManagedThreadId);await Task.Delay(100);Console.WriteLine($"{i++}");}}
}
运行结果如下
DoLo Thread:1
Main Thread:1
1
DoLo Thread:4
2
DoLo Thread:4
3
DoLo Thread:4
4
DoLo Thread:4
5相关文章:
C# Task 包含 await ConfigureAwait CancellationTokenSource
Task以下是 Task 类的一些关键特性和用法:以下是一些使用 Task 的示例:创建并启动一个任务使用 await 等待任务完成处理任务异常使用 Task<TResult> 获取结果取消任务总结 await暂停方法执行:非阻塞调用:任务结果获取&#…...
Python数据分析与建模库-02科学计算库Numpy01-05合集
1、该视频主要讲述了南派(NumPy)的核心操作和数据结构,以及如何使用NumPy库读取和处理数据。 2、该视频主要讲述了在编程中,如何对数组或矩阵中的元素进行判断和操作,以及在单排中如何进行类型转换。 3、该视频主要讲…...
【前端项目笔记】1 登录与登出功能实现
项目笔记 ☆☆代表面试常见题 前后端分离:后端负责写接口,前端负责调接口。 登录/退出功能 登录业务流程 登录页面:用户名密码 调用后台接口进行验证 通过验证,根据后台响应状态跳到项目主页 登录业务相关技术点࿱…...
是字符串定义以及在C语言中字符串是如何表示的
字符串(String)是由零个或多个字符(包括空格)组成的有限序列,常用于文本数据的存储和处理。在编程中,字符串是常见的数据类型。 在C语言中,字符串不是一种内置的数据类型,但C语言提…...
辽宁普通测径仪升级智能测径仪后都有哪些改进?
关键字: 普通测径仪, 智能测径仪, 测径仪升级, 测径仪特点, 智能测径仪优势, 目前多数厂家测径仪的数据处理方式是单片机计算出最终结果,然后传输到工控机后期处理。这样的电路系统对轧钢现场的高温、高粉尘和强电磁干扰的环境适应性很差,使得同一厂家、…...
【微信小程序】事件分类以及阻止事件冒泡
在微信小程序中,事件分为冒泡事件和非冒泡事件两大类,它们的区别在于事件是否能从原始触发组件开始,向父级组件传播(即“冒泡”)。 冒泡事件:当一个组件上的事件被触发后,不仅当前组件会接收到这…...
踩坑!被node-sass折磨的一天
文章目录 被node-sass折磨的一天折磨过程了解原因注意事项 被node-sass折磨的一天 折磨过程 起因是要开发一个老项目,照常拉代码、下依赖、启动三步走 依赖开始下载不对了,以为是node版本问题,寻找node-sass对应的node版本 利用nvm&#…...
App UI 风格打造独特体验
App UI 风格打造独特体验...
【学习笔记8】阅读StyleID论文源码
论文【链接】 源码【链接】 一、DDIM eta ddim_step表示执行几轮去噪迭代,eta表示DDPM和DDIM的插值系数。当eta0时,为DDPM;当eta≠0时,为DDIM。 参考 DDIM 简明讲解与 PyTorch 实现:加速扩散模型采样的通用方法 【s…...
wordpress旅游网站模板
旅行社wordpress主题 简洁实用的旅行社wordpress主题,适用于旅行社建网站的wordpress主题模板。 https://www.jianzhanpress.com/?p4296 旅游WordPress主题 简洁实用的旅游WordPress主题,适合做旅游公司网站的WordPress主题模板。 https://www.jian…...
vs2019 c++20规范 STL 库中头文件 <atomic> 源码注释及探讨几个知识点
(1 探讨一) 模板类 atomic 的继承关系与数据结构如下: (2 探讨二 ) 可见 atomic 的 fetch_xx 函数,返回的都是 atomic 中存储的旧值。测试如下: 谢谢...
Flink任务如何跑起来之 2.算子 StreamOperator
Flink任务如何跑起来之 2.算子 StreamOperator 前文介绍了Transformation创建过程,大多数情况下通过UDF完成DataStream转换中,生成的Transformation实例中,核心逻辑是封装了SimpleOperatorFactory实例。 UDF场景下,DataStream到…...
学习笔记——路由网络基础——路由优先级(preference)
1、路由优先级(preference) 路由优先级(preference)代表路由的优先程度。当路由器从多种不同的途径获知到达同一个目的网段的路由(这些路由的目的网络地址及网络掩码均相同)时,路由器会比较这些路由的优先级,优选优先级值最小的路由。 路由来源的优先…...
数据预处理——调整方差、标准化、归一化(Matlab、python)
对数据的预处理: (a)、调整数据的方差; (b)、标准化:将数据标准化为具有零均值和单位方差;(均值方差归一化(Standardization)) (c)、最值归一化,也称为离差标准化,是对原始数据的…...
opencv_特征检测和描述
理解特征 寻找独特的特定模式或特定特征,可以轻松跟踪和比较。 拼图:在图像中搜索这些特征,找到它们,在其他图像中查找相同的特征并对齐它们。而已。 基本上,角被认为是图像中的好特征。 在本单元中,我…...
CID引流电商下的3C产品选品策略深度解析
摘要:随着电商行业的迅猛发展和消费者需求的日益多样化,CID引流电商作为一种新兴的电商模式,逐渐受到了广泛关注。在这一模式下,3C产品作为高客单价、高技术含量的代表品类,其选品策略的制定显得尤为重要。本文将从多…...
DeepSORT(目标跟踪算法)中的状态向量与状态转移矩阵
DeepSORT(目标跟踪算法)中的状态向量与状态转移矩阵 flyfish 状态转移矩阵(State Transition Matrix)F的构造 这篇是一定要看的,拖到文章的最后部分,需要理解状态转移矩阵怎么来的,怎么是这个…...
李宏毅深度学习01——基本概念简介
视频链接 基本概念 Regression(回归): 类似于填空 Classification(分类): 类似于选择 Structure Learning(机器学习): ?? 机器学习找对应函数…...
TcpClient 服务器、客户端连接
TcpClient 服务器 TcpListener 搭建tcp服务器的类,基于socket套接字通信的 1 创建服务器对象 TcpListener server new TcpListener(IPAddress.Parse("127.0.0.1"), 3000); 2 开启服务器 设置最大连接数 server.Start(1000); 3 接收客户端的链接,只能…...
13大最佳工程项目管理系统软件盘点
国内外主流的13款工程项目管理系统软件:Worktile、中建软件、泛微建筑项目管理软件、LiquidPlanner、Wrike、建文软件、广联达、Microsoft Project、泛普软件、Procore、Buildertrend、Fieldwire、Autodesk Construction Cloud。 在快速变化的工程领域,有…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
C++ 类基础:封装、继承、多态与多线程模板实现
前言 C 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类…...
