C#学习相关系列之多线程---ConfigureAwait的用法

2023-10-30 13:52

本文主要是介绍C#学习相关系列之多线程---ConfigureAwait的用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、ConfigureAwait的作用

        ConfigureAwait方法是Task类中的一个实例方法,它用于配置任务的运行上下文。运行上下文指的是任务在执行期间所处的环境,包括线程、同步上下文等。ConfigureAwait方法接受一个布尔值参数,用于决定是否捕获上下文。当参数为true时,表示任务会在之前的上下文中继续执行。当参数为false时,表示任务会在不同的上下文中执行。 ConfigureAwait方法的原理是通过设置Task对象的一个内部状态来实现的。当调用ConfigureAwait方法时,会创建一个新的Task对象,并将原始Task对象的状态复制给该新的Task对象。新的Task对象会在执行时,根据参数值决定是否将上下文捕获。

        通俗的讲,ConfigureAwait可以取决任务之后的代码是继续返回主线程执行还是在新开的线程中继续执行。

二、代码示例

ConfigureAwait在界面中应用最明显:

private void button1_Click(object sender, EventArgs e){MessageBox.Show($"开始运行,ThreadId:{Thread.CurrentThread.ManagedThreadId}", "button1_Click");Test();MessageBox.Show($"运行结束,ThreadId:{Thread.CurrentThread.ManagedThreadId}", "button1_Click");}public static void Test(){var task = XXXAsync(); // 开启异步任务,比如下载某个资源var resuslt = task.Result; // 获取异步任务的结果显示给用户,这里会阻塞当前ui线程直到异步线程返回结果MessageBox.Show($"XXXAsync运行结束显示异步任务结果:{resuslt},ThreadId:{Thread.CurrentThread.ManagedThreadId}", "Test");}private static async Task<string> XXXAsync(){await Task.Delay(1000);  // 这里会导致死锁//await Task.Delay(1000).ConfigureAwait(false); // 这样就不会死锁MessageBox.Show($"XXXAsync运行结束,ThreadId:{Thread.CurrentThread.ManagedThreadId}", "XXXAsync");return "XXXAsync.Result";}

 async /await 出现时var resuslt = task.Result会等待任务执行,直到XXXAsync()有返回结果才会继续执行主线程也就是var resuslt = task.Result在主线程中挂起,一直占用主线程,但await任务后 MessageBox.Show($"XXXAsync运行结束,ThreadId:{Thread.CurrentThread.ManagedThreadId}", "XXXAsync");代码是在同步执行,是在主线程上进行,由于主线程被var resuslt = task.Result一直占用,await代码就会无法在主线程上执行,出现卡死现象。

ConfigureAwait则会解决该问题,当ConfigureAwait(true)时,则是返回主线程执行await后续代码,也是默认情况出现卡死,ConfigureAwait(false)时就会解决该问题,await后的代码会在支线程继续执行,不会出现该问题。

注意: async /await 返回为task与var resuslt = task.Result连用时,await后的任务ConfigureAwait的属性设置为false避免假死。

在非界面代码上进行测试:

        static void Main(string[] args){Console.WriteLine("开始执行程序");Console.WriteLine("这是主函数:{0}", Thread.CurrentThread.ManagedThreadId);var task = tt();var result = task.Result;Console.WriteLine("运行结果为:"+result+"  "+ Thread.CurrentThread.ManagedThreadId);Console.Read();}public static async Task<string> tt(){await Task.Run(() =>{Console.WriteLine("这是等待方法异步线程:{0}", Thread.CurrentThread.ManagedThreadId);}).ConfigureAwait(true);Console.WriteLine("这是异步方法剩余内容:{0}", Thread.CurrentThread.ManagedThreadId);return "异步方法完成";}

await后续代码并没有返回主线程执行,而是直接在支线程执行,并没有出现卡死的情况。猜想或许只有在界面操作时才会出现假死情况!在后续中也会继续留意该问题!

这篇关于C#学习相关系列之多线程---ConfigureAwait的用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/308372

相关文章

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

python多线程并发测试过程

《python多线程并发测试过程》:本文主要介绍python多线程并发测试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、并发与并行?二、同步与异步的概念?三、线程与进程的区别?需求1:多线程执行不同任务需求2:多线程执行相同任务总结一、并发与并行?1、

javascript fetch 用法讲解

《javascriptfetch用法讲解》fetch是一个现代化的JavaScriptAPI,用于发送网络请求并获取资源,它是浏览器提供的全局方法,可以替代传统的XMLHttpRequest,这篇... 目录1. 基本语法1.1 语法1.2 示例:简单 GET 请求2. Response 对象3. 配置请求

Go 语言中的 Struct Tag 的用法详解

《Go语言中的StructTag的用法详解》在Go语言中,结构体字段标签(StructTag)是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如JSON、XML)、ORM映... 目录一、结构体标签的基本语法二、json:"token"的具体含义三、常见的标签格式变体四、使用示例五、使用

mysql中的group by高级用法详解

《mysql中的groupby高级用法详解》MySQL中的GROUPBY是数据聚合分析的核心功能,主要用于将结果集按指定列分组,并结合聚合函数进行统计计算,本文给大家介绍mysql中的groupby... 目录一、基本语法与核心功能二、基础用法示例1. 单列分组统计2. 多列组合分组3. 与WHERE结合使

C#使用MQTTnet实现服务端与客户端的通讯的示例

《C#使用MQTTnet实现服务端与客户端的通讯的示例》本文主要介绍了C#使用MQTTnet实现服务端与客户端的通讯的示例,包括协议特性、连接管理、QoS机制和安全策略,具有一定的参考价值,感兴趣的可... 目录一、MQTT 协议简介二、MQTT 协议核心特性三、MQTTNET 库的核心功能四、服务端(BR

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py

MySQL 字符串截取函数及用法详解

《MySQL字符串截取函数及用法详解》在MySQL中,字符串截取是常见的操作,主要用于从字符串中提取特定部分,MySQL提供了多种函数来实现这一功能,包括LEFT()、RIGHT()、SUBST... 目录mysql 字符串截取函数详解RIGHT(str, length):从右侧截取指定长度的字符SUBST

Python多进程、多线程、协程典型示例解析(最新推荐)

《Python多进程、多线程、协程典型示例解析(最新推荐)》:本文主要介绍Python多进程、多线程、协程典型示例解析(最新推荐),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 目录一、multiprocessing(多进程)1. 模块简介2. 案例详解:并行计算平方和3. 实现逻

C#实现访问远程硬盘的图文教程

《C#实现访问远程硬盘的图文教程》在现实场景中,我们经常用到远程桌面功能,而在某些场景下,我们需要使用类似的远程硬盘功能,这样能非常方便地操作对方电脑磁盘的目录、以及传送文件,这次我们将给出一个完整的... 目录引言一. 远程硬盘功能展示二. 远程硬盘代码实现1. 底层业务通信实现2. UI 实现三. De