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语言中%zu的用法解读

《C语言中%zu的用法解读》size_t是无符号整数类型,用于表示对象大小或内存操作结果,%zu是C99标准中专为size_t设计的printf占位符,避免因类型不匹配导致错误,使用%u或%d可能引发... 目录size_t 类型与 %zu 占位符%zu 的用途替代占位符的风险兼容性说明其他相关占位符验证示

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

全面解析Golang 中的 Gorilla CORS 中间件正确用法

《全面解析Golang中的GorillaCORS中间件正确用法》Golang中使用gorilla/mux路由器配合rs/cors中间件库可以优雅地解决这个问题,然而,很多人刚开始使用时会遇到配... 目录如何让 golang 中的 Gorilla CORS 中间件正确工作一、基础依赖二、错误用法(很多人一开

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con