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

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

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

相关文章

导弹拦截(最大不上升 或 不下降子序列,dp)

算法分析&#xff1a; 1.求最长子序列 1.每次输入时&#xff0c;计算每个元素对应的序列的长度 1.向前遍历找大于当前元素的数 2.若之前元素对应长度1 大于当前长度&#xff0c;更新当前长度 2.若当前元素对应长度 大于最大长度&#xff0c;更新最大长度 2.dilworth定理 故需…

HarmonyOS开发:NodeJs脚本实现组件化动态切换

前言 上篇文章&#xff0c;我们使用NodeJs脚本完成了HarmonyOS项目的组件化运行&#xff0c;但是由于脚本是基于4.0.0.400版本的DevEco Studio开发的&#xff0c;可能在配置文件的修改上有些许差距&#xff0c;那么遇到这种情况怎么办&#xff0c;一种是再写一套针对性的脚本文…

系列四十二、Spring的事务传播行为案例演示(二)#REQUIRED

一、演示Spring的默认传播行为&#xff08;REQUIRED&#xff09; 1.1、运行之前表中的数据 1.2、StockServiceImpl /*** Author : 一叶浮萍归大海* Date: 2023/10/30 15:43* Description:*/ Service(value "stockServiceREQUIRED") public class StockServiceImpl…

MSQL系列(十) Mysql实战-Join驱动表和被驱动表如何区分

Mysql实战-Join驱动表和被驱动表如何区分 前面我们讲解了Mysql的查询连接Join的算法原理, 我发现大家都知道小表驱动大表,要让小表作为驱动表, 现在有2个问题 查询多表, 到底哪个是驱动表?哪个是被驱动表, 如何区分?索引如何优化,到底是加在驱动表上,还是被驱动表上? &…

二维数组如何更快地遍历

二维数组如何更快地遍历 有时候&#xff0c;我们会发现&#xff0c;自己的代码和别人的代码几乎一模一样&#xff0c;但运行时间差了很多&#xff0c;别人是 AC \text{AC} AC&#xff0c;你是 TLE \text{TLE} TLE&#xff0c;这是为什么呢&#xff1f; 一个可能的原因是数组的…

2023高德地图poi资源下载

全国8千万地图poi地图数据&#xff1a;含名称、地址、电话、省份、城市、区县、经纬度、电话等信息

第五章 I/O管理 六、I/O核心子系统

目录 一、核心子系统 1、I/O调度 2、设备保护 二、假脱机技术 1、脱机&#xff1a; 2、假脱机&#xff08;SPOOLing技术&#xff09;&#xff1a; 3、应用&#xff1a; 1.独占式设备&#xff1a; 2.共享设备&#xff1a; 4、共享打印机原理分析 三、总结 一、核心子系…

metaRTC集成flutter ui demo编译指南

概要 Flutter是由Google开发的开源UI工具包&#xff0c;用于构建跨平台应用程序&#xff0c;支持linux/windows/mac/android/ios等操作系统。 metaRTC新增flutter demo&#xff0c;支持linux/windows/mac/android/ios操作系统&#xff0c;此demo在ubuntu桌面环境下测试成功。…

Jenkins项目部署

使用jenkins部署项目 简易版使用jenkins部署项目 将war包部署到tomcat中 将已有的war包部署到tomcat中(jenkins与tomcat在同一台主机) 点击Jenkins主页的新建任务 输入任务名称 选择构建一个自由风格的软件项目后点击确定 在构建内添加构建步骤&#xff0c;选择执行shell 输入…

时间序列预测大模型-TimeGPT

时间序列预测领域正在经历一个非常激动人心的时期。仅在过去的三年里&#xff0c;我们就看到了许多重要的贡献&#xff0c;例如N-BEATS、N-HiTS、PatchTST和TimesNet。 与此同时&#xff0c;大型语言模型 (LLM)最近在 ChatGPT 等应用程序中广受欢迎&#xff0c;因为它们无需进…

自动化项目实战 [个人博客系统]

自动化博客项目 用户注册登录验证效验个人博客列表页博客数量不为 0 博客系统主页写博客 我的博客列表页效验 刚发布的博客的标题和时间查看 文章详情页删除文章效验第一篇博客 不是 "自动化测试" 注销退出到登录页面,用户名密码为空 用户注册 Order(1)Parameterized…

Spring Cloud之API网关(Zuul)

目录 Zuul 简介 功能 工作流程 搭建 1.引入依赖 2.添加注解 3.路由转发 4.测试 实现原理 EnableZuulProxy注解 ZuulServlet FilterProcessor Zuul内置过滤器 常用配置 Zuul 简介 zuul是SpringCloud子项目的核心组件之一&#xff0c;可以作为微服务架构中的API网…

【C】C语言文件操作

1.为什么使用文件 我们前面学习结构体时&#xff0c;写通讯录的程序&#xff0c;当通讯录运行起来的时候&#xff0c;可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯录中的数据自然就不存在了&#xff0c;等下…

超全整理,Jmeter性能测试-脚本error报错排查/分布式压测(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能脚本error报错…

域名系统 DNS

DNS 概述 域名系统 DNS(Domain Name System)是因特网使用的命名系统&#xff0c;用来把便于人们使用的机器名字转换成为 IP 地址。域名系统其实就是名字系统。为什么不叫“名字”而叫“域名”呢&#xff1f;这是因为在这种因特网的命名系统中使用了许多的“域(domain)”&#x…

S5PV210裸机(九):ADC

本文主要探讨210的ADC相关知识。 ADC ADC:模数转换&#xff08;模拟信号转数字信号&#xff09; 量程:模拟电压信号范围(210为0&#xff5e;3.3V) 精度:若10二进制位来表示精度&#xff08;210为10位或12位&#xff09;,量…

线性代数 第三章 向量

一、运算 加法、数乘、内积 施密特正交化 二、线性表出 概念&#xff1a;如果&#xff0c;则称可由线性表出&#xff08;k不要求不全为0&#xff09; 判定&#xff1a; 非齐次线性方程组有解无关&#xff0c;相关 如果两个向量组可以互相线性表出&#xff0c;则称这两个…

Xilinx 7 系列 1.8V LVDS 和 2.5V LVDS 信号之间的 LVDS 兼容性

如果通过LVDS进行接口&#xff0c;可以按照以程图中的步骤操作&#xff0c;以确保满足正确使用LVDS的所有要求。 40191 - 7 系列 - 1.8V LVDS 和 2.5V LVDS 信号之间的 LVDS 兼容性 与LVDS兼容驱动器和接收器连接时&#xff0c;7系列LVDS和LVDS_25输入和输出应该不存在兼容性问…

案例分析真题-系统建模

案例分析真题-系统建模 2009年真题 【问题1】 【问题2】 【问题3】 2012年真题 【问题1】 【问题2】 【问题3】 2014年真题 【问题1】 【问题2】 骚戴理解&#xff1a;这个题目以前经常考&#xff0c;不知道今年会不会考&#xff0c;判断的话就是看加工有没有缺少输入和输出&a…

C++面试——多线程详解

C11提供了语言层面上的多线程&#xff0c;包含在头文件<thread>中。它解决了跨平台的问题&#xff0c;提供了管理线程、保护共享数据、线程间同步操作、原子操作等类。C11 新标准中引入了5个头文件来支持多线程编程&#xff0c;如下图所示&#xff1a; 多进程与多线程 多…