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。 在快速变化的工程领域,有…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...