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的更多相关文章

  1. C#~异步编程再续~await与async引起的w3wp.exe崩溃

    返回目录 最近怪事又开始发生了,IIS的应用程序池无做挂掉,都指向同一个矛头,async,threadPool,Task,还有一个System.NullReferenceException,所以这些都 ...

  2. async 和 await小结

    三大返回值: 返回类型 - Task<TResult> 返回类型 - Task 返回类型 - void 当你添加 async 关键字后,需要返回一个将用于后续操作的对象,请使用 Task& ...

  3. 走进异步世界-犯傻也值得分享:ConfigureAwait(false)使用经验分享

    在上周解决“博客程序异步化改造之后遭遇的性能问题”的过程中,我们干了一件自以为很有成就感的事——在表现层(MVC与WebForms)将所有使用await的地方都加上了ConfigureAwait(fa ...

  4. C# SemaphoreSlim 实现

    当多个任务或线程并行运行时,难以避免的对某些有限的资源进行并发的访问.可以考虑使用信号量来进行这方面的控制(System.Threading.Semaphore)是表示一个Windows内核的信号量对 ...

  5. ConfigureAwait(false)

    昨天在做项目的时候,用的dapper查数据用的QueryAsync 异步方法.给上级做代码审核时,上级说最好加上ConfigureAwait(false).能减少一些性能开销. 因为之前没用过所以看了 ...

  6. 异步编程之Async,Await和ConfigureAwait的关系

    在.NET Framework 4.5中,async / await关键字已添加到该版本中,简化多线程操作,以使异步编程更易于使用.为了最大化利用资源而不挂起UI,你应该尽可能地尝试使用异步编程.虽然 ...

  7. Async,Await和ConfigureAwait的关系

    [转自]https://mp.weixin.qq.com/s/h10V-FshGoaQUWFPfy-azg 在.NET Framework 4.5中,async / await关键字已添加到该版本中, ...

  8. SemaphoreSlim 实现

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/dz45693/article/deta ...

随机推荐

  1. hhtp协议和html标签分类css

    HTTP协议四大特性: 1基于请求响应 2 基于tcp/ip协议之上的应用层协议 3 无状态 不能保存用户信息 4 无链接,短链接 二 get和post的区别? 1 get 不安全,get请求没有请求 ...

  2. axios post params(post像get一样使用params传参)

    今天有一个接口是/create?name=***&age=****,但是是一个post请求,我只见过get的这种请求. 找了好久- 解决方法: 发表的axios签名是axios.post(ur ...

  3. DNS CNAME limitations cname 在哪些情况下不能配置

    https://www.rfc-editor.org/rfc/rfc1912.html https://www.rfc-editor.org/rfc/rfc2181.html 说明: domain n ...

  4. [复现]2021 DASCTF X BUUOJ 五月大联动-PWN

    [复现]2021 DASCTF X BUUOJ 五月大联动 由于我没ubuntu16就不复现第一个题了,直接第二个 正常的off by one from pwn import * context.os ...

  5. vue3-使用百度地图遇到的坑-地图实例化

    1.创建地图实例 原因:在使用vue3为了只定义一次地图实例,在所有方法中使用,直接使用如下定义方式: setup() { const data = reactive({ bmap: null,}) ...

  6. USB TTL CMOS 电平

    USB转TTL模块的作用就是把电平转换到双方都能识别进行通信. TTL电平信号规定,+5V等价于逻辑"1",0V等价于逻辑"0"(采用二进制来表示数据时).这样 ...

  7. 基于leaflet地图可视化(一)

    最近,在学习地图可视化是基于公司的项目.但公司在项目上居然用图片来代替.无语~~~项目效果图(第一版)如下: 突发奇想,2016年自己就接触过地图可视化.但那是没有深入研究.只会用R语言来实现点基础. ...

  8. Redis-Cluster常用命令

    CLUSTER INFO 打印集群的信息 CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息. //节点 CLUSTER MEET <ip> < ...

  9. 当我把ChatGPT拉进群聊里,我的朋友都玩疯了

    前言 近期ChatGPT可以说是太火了,问答.写论文.写诗.写代码,只要输入精确的prompt,他的表现总是让人惊喜.本着打不过就加入的原则.要是把ChatGPT拉入群聊中,会是怎样一番场景?说做就做 ...

  10. Spring Security 框架使用

    更多内容,前往IT-BLOG 一.Spring Security 简介 Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供 ...