C# ConfigureWait
ConfigureAwait
参数为bool类型。true:尝试将延续任务封送回原始上下文
我们一般使用的是false,用于避免强制在原始上下文或调度程序中进行回调。
原理:
以await DoSomeThingAsync().ConfigureAwait(false)为例。
await等待返回后,需要获取上下文(比如UI)的线程,然后继续执行后续的代码。
本来是回到UI线程去执行的,这里添加了ConfigureAwait(false)后,就从线程池中使用工作线程去执行后续代码了。
1 private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
2 {
3 Debug.WriteLine($"ButtonBase_OnClick-start");
4 await DoA();
5 Debug.WriteLine($"ButtonBase_OnClick-end");
6 }
7 private async Task DoA()
8 {
9 Debug.WriteLine($"DoA-start");
10 await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false);
11 Debug.WriteLine($"DoA-end");
12 }
如上代码,输出调试信息位置的几处,所处线程分别是:
ButtonBase_OnClick-start -- UI线程
DoA-start -- UI线程
DoA-end -- 工作线程
ButtonBase_OnClick-end -- UI线程
可以看出,DoA方法中调用ConfigureAwait(false)后后续代码可以在新的工作线程中执行,ButtonBase_OnClick不调用则会默认切换至UI线程继续执行后续代码。
使用-提升性能
减少了回调原始线程(比如UI线程),可以适当减少因排队回调次数过多造成的性能影响
不必要回到原始线程,可以减少原始线程的处理。这也是多线程编程的一个实现方式。
使用-避免死锁
什么情况会死锁?
当你基于某些原因(比如想将异步方法转同步、或者仅仅只是想等待完成),使用了.Wait()、.Result、GetAwaiter().GetResult()方法时,可能会出现死锁。
1 private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
2 {
3 Debug.WriteLine($"ButtonBase_OnClick-start");
4 DoA().Wait();
5 Debug.WriteLine($"ButtonBase_OnClick-end");
6 }
7 private async Task DoA()
8 {
9 Debug.WriteLine($"DoA-start");
10 await Task.Delay(TimeSpan.FromSeconds(5));
11 Debug.WriteLine($"DoA-end");
12 }
如上,当使用了.Wait()后,在DoA方法中有任务等待,就会出现死锁。
为什么会死锁?
以上方法,是通过同步阻塞的方式来完成等待的。我们的UI上下文只有一个线程(并发数量是1),在调用以上方法后,子方法中await无法回调至UI线程(因为唯一的线程已经被阻塞了)。
怎么解决死锁?
在await DoSomeThingAsync()后添加.ConfigureAwait(false),那么它就不会将回调排队送回原始上下文,进而避免了死锁。
其实就是假装没有上下文,然后默认让线程池线程处理。
一些问题
1.使用.ConfigureAwait(false)后,后续代码中有调用UI线程如控件,会有线程调度异常
-- 建议在UI层,不使用.ConfigureAwait(false)。或者只对需要调用UI线程的代码,添加切换至UI线程的逻辑(如Dispatcher.InvokeAsync)
2.添加.ConfigureAwait(false)后,后续的代码并没有预期的在工作线程执行。
-- 这是可能的。因为await需要等待时,才会需要切换至原始上下文。当等待已经完成的Task时,后续代码将会保持同步运行,无需上下文的回调
以上是个人总结后,相对简单、重要的部分。
你也可以看看其它:
C# ConfigureWait的更多相关文章
- C#~异步编程再续~await与async引起的w3wp.exe崩溃
返回目录 最近怪事又开始发生了,IIS的应用程序池无做挂掉,都指向同一个矛头,async,threadPool,Task,还有一个System.NullReferenceException,所以这些都 ...
- async 和 await小结
三大返回值: 返回类型 - Task<TResult> 返回类型 - Task 返回类型 - void 当你添加 async 关键字后,需要返回一个将用于后续操作的对象,请使用 Task& ...
- 走进异步世界-犯傻也值得分享:ConfigureAwait(false)使用经验分享
在上周解决“博客程序异步化改造之后遭遇的性能问题”的过程中,我们干了一件自以为很有成就感的事——在表现层(MVC与WebForms)将所有使用await的地方都加上了ConfigureAwait(fa ...
- C# SemaphoreSlim 实现
当多个任务或线程并行运行时,难以避免的对某些有限的资源进行并发的访问.可以考虑使用信号量来进行这方面的控制(System.Threading.Semaphore)是表示一个Windows内核的信号量对 ...
- ConfigureAwait(false)
昨天在做项目的时候,用的dapper查数据用的QueryAsync 异步方法.给上级做代码审核时,上级说最好加上ConfigureAwait(false).能减少一些性能开销. 因为之前没用过所以看了 ...
- 异步编程之Async,Await和ConfigureAwait的关系
在.NET Framework 4.5中,async / await关键字已添加到该版本中,简化多线程操作,以使异步编程更易于使用.为了最大化利用资源而不挂起UI,你应该尽可能地尝试使用异步编程.虽然 ...
- Async,Await和ConfigureAwait的关系
[转自]https://mp.weixin.qq.com/s/h10V-FshGoaQUWFPfy-azg 在.NET Framework 4.5中,async / await关键字已添加到该版本中, ...
- SemaphoreSlim 实现
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/dz45693/article/deta ...
随机推荐
- thread互斥测试
thread互斥测试 实践代码 #include <stdio.h> #include <stdlib.h> #include <pthread.h> //linu ...
- HTML笔记(二) HTML标签元素
一 常用的头部元素标签 <head>元素包含了所有的头部标签元素. 1.<title> <title>标签定义了HTML文档的标题,在HTML/XHTML文档中是必 ...
- JDMasking v0.1.0-beta 发布
JDMasking 全称是jdbc data masking,是一款零代码修改.无重启.基于JDBC的动态数据脱敏软件. JDMasking 主要对实现jdbc的驱动进行字节码的增强,支持对运行中的程 ...
- DataX Web可视化分布式调度数据同步系统
因项目需要,结合目前参与的项目,以及个人技术能力范围,组合研发一套web可视化数据同步系统,正式名称:DataXP. 项目背景:接触过阿里云这类大数据平台,对于中大型项目以及需要与外部系统对接数据的情 ...
- Apache和Nginx有什么区别,如何选择?
Apache和Nginx都是大名鼎鼎的Web服务器软件. 网上已经有非常多关于apache和nginx区别的文章了,笔者就不从专业技术的角度进行解说,而按照目前比较流行的架构方式进行阐述. 1.安全性 ...
- Windows 任务栏透明 居中
任务栏设置 任务栏居中 由于windows默认的程序是从左往右显示,看着可能有一点不舒服,当然如果使用习惯的话,忽然居中,可能更不舒服 首先搜索字符映射表 点击字符映设表中第五行的空白字符,选择进行复 ...
- CF1286F Harry The Potter
CF1286F Harry The Potter 首先答案上界为 \(n\),就是对每个点用一次操作 1. 那么我们现在的思维模式就是利用操作 2 来减少操作 1 的次数. 不难发现,如果操作 2 的 ...
- 第四朵“云”!全托管的时序数据云平台 TDengine Cloud 正式支持阿里云
3 月 13 日,全托管的时序数据处理云服务平台 TDengine Cloud 正式支持阿里云,这是继 Microsoft Azure.AWS.Google Cloud 后 TDengine Clou ...
- Java输入与输出语句详细解析
前言 我们在前面的文章中,学习了如何创建Java文件,也学习了Java里的标识符.运算符.进制等内容.有些同学觉得还不够过瘾,给壹哥发来了好多私信,期待我能够把进度更新的再快一点.这不,新内容这就给大 ...
- java多线程--2 静态代理、Lambda表达式
java多线程--2 静态代理.Lambda表达式 静态代理 package com.ssl.demo02; //静态代理 //真实对象和代理对象都要实现同一个接口 //代理对象必须要代理真实角色 / ...