C#语言中的Async/await最佳实践

自从 C# 5 中引入 async/await 以来,开发人员之间一直对 async/await 关键字的最佳实践以及幕后实际发生的事情感到困惑。

让我们先从基础开始。

在 Windows 窗体的早期,UI 延迟与 I/O 操作所花费的时间成正比。这意味着,如果您尝试将数据保存到数据库中,并且数据库调用需要 20 秒,则用户只能等待这 20 秒。这是一个糟糕的用户体验(无论如何,在 2012 年之前谁关心用户体验)。

然后引入了 async/await。现在我们有了一种在两个线程之间划分工作的方法:

  1. UI 线程

  2. 工作线程

主代码在命中 await 关键字后立即由 UI 线程运行。在那一刻,UI线程可以自由地做其他事情,线程池中的另一个线程将接管做繁重的事情。

一旦我们从 DB 获得可用的数据,我们调用 UI 线程来执行 await 关键字之后的下一步指令。

这是用户可以与UI上的其他一些元素进行交互,直到数据被提取。

目前为止,一切都好?

现在让我们一一谈谈快速的最佳实践!

  1. **切勿使用 .Wait() 或 .结果:**它将锁定线程,您最终将使用更多线程来完成工作。始终使用 await,或者如果需要进行同步调用,请使用 .GetAwaiter() 中。GetResult()。

  2. 永远不要将 void 方法标记为异步 — 您需要查看异步方法引发的异常,对吗?如果你将 void 方法标记为异步,你的内部异常将被吞噬,并且(你知道)调试和找到这些异常会很痛苦。

  3. 始终等待您的异步 — 在没有 await 关键字的情况下使用异步方法没有任何好处。然后是一个同步调用。

  4. 如果代码有 9/10 次从不使用 await 关键字的热路径(如缓存)获取值,则使用 ValueTask 返回类型而不是 Task。

  5. 将 IAsyncEnumerable 用于流式处理数据。这意味着,如果存在集合数据巨大并且需要以块形式接收数据的情况,则使用 IAsyncEnumerable。

  6. ConfigureAwait — 好吧,我知道这对你来说是一场噩梦,但我会非常简单地解释这一点。如果未使用 ConfigureAwait(false) 方法标记 await 语句,它将调用相同的 UI 线程或工作线程(导致 await 语句的线程)以在 await 之后执行下一组指令。为什么这很糟糕?如果您的工作线程或 UI 线程正忙于执行其他操作,并且在等待后被调用执行下一组语句,该怎么办?

图片

默认情况下,ConfigureAwait(true) 值为 true。需要将其标记为 ConfigureAwait(false)。这将告诉编译器使用 threadpool 中的任何线程在 await 关键字之后执行语句,而不是特别调用 await 语句的线程。

4. 避免返回 await:如果中介类方法只是返回 await 方法,请不要用 async/await 标记它们。除了尝试/捕捉或使用

不良做法: 

图片

良好做法:

为什么?:它增加了使用 async/await 关键字的额外复杂性。在后台,编译器将异步方法转换为类。我们希望在中间类中做的就是一个返回任务的方法。调用的方法已经是“异步”和“等待”。我们不需要在每一步都这样做。

ConfigureAwait 仅在使用 SynchronizationContext 的框架中有用。ASP.Net Core 等 Web 应用框架没有 SynchronizationContext。因此,ConfigureAwait true/false 在 Web 应用程序中没有多大用处。

如果你喜欢我的文章,请给我一个赞!谢谢

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

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

相关文章

ResNet——Deep Residual Learning for Image Recognition(论文阅读)

论文名:Deep Residual Learning for Image Recognition 论文作者:Kaiming He et.al. 期刊/会议名:CVPR 2016 发表时间:2015-10 ​论文地址:https://arxiv.org/pdf/1512.03385 1.什么是ResNet ResNet是一种残差网络&a…

【八股系列】介绍React高阶组件,适用于什么场景?

文章目录 1. HOC的工作原理2. 返回的新组件3. 适用场景4. 注意事项5. 示例代码 React高阶组件( Higher-Order Components,简称HOC)是 React中一种高级的 复用组件逻辑的技术。 HOC自身不是 React API的一部分,而是基于 Reac…

【Spine学习05】之网格权重概念,以及让小臂动起来

上一节绑定好骨骼设置好了父级之后呢, 会发现操纵只有大臂能摆动,但是小臂以及手部无法K帧动起来。 当然如果你拿到的图片分层非常细,大小腿分开 例如这种的,铠甲勇士,那么其实绑不绑定权重意义不大, 因为骨…

职教本科人工智能工程技术教学解决方案

前言 随着人工智能技术的迅猛发展,其在各行各业的应用日益广泛,对高层次技术技能型人才的需求也愈发迫切。在这一背景下,职业教育本科层次的人工智能工程技术专业应运而生,旨在培养能够从事人工智能数据处理、模型构建、系统应用研…

echarts legend 背景色渐变

问题与本文无关&#xff1a;如果检测软件显示loadsh.js 的版本是4.17.10 装element-ui 2.15.8版本以下&#xff0c;2.15.6经过测试可以 代码&#xff1a; <template><div class"levelMain"><div class"survey-head"><div class"…

【思考】Vue2响应丢失、$set

【思考】Vue2响应丢失、$set vue2响应丢失情况复现原因解决总结 vue2响应丢失情况复现 场景&#xff1a;直接通过数组下标去修改数组造成响应丢失 <template><div><p v-for"(item, index) in list" :key"index">{{item}}</p><…

同三维T80004EHL-W-4K30 4K HDMI编码器,支持WEBRTC协议

输入&#xff1a;1路HDMI1路3.5音频&#xff0c;1路HDMI环出1路3.5音频解嵌输出 4K30超高清,支持U盘/移动硬盘/TF卡录制&#xff0c;支持WEBRTC协议&#xff0c;超低延时&#xff0c;支持3个点外网访问 1个主流1个副流输出&#xff0c;可定制选配POE供电模块&#xff0c;WEBR…

【Vue】——组件的注册与引用(二)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

VBA学习(4):一键生成Sheet表目录

当Sheet表非常多的时候&#xff0c;一般我们会在第一张工作表中做一张目录&#xff0c;方便快速查找定位相应表格&#xff0c;以下示例将介绍如何通过宏程序一键生成目录。 效果如下&#xff1a; 参考代码如下&#xff1a; Sub SheetList()Dim sht As Worksheet, i As Long, s…

uniapp canvas生成海报

效果 封装组件&#xff0c;父组件 ref 调用 downImgUrl()函数&#xff0c;其他根据自己需求改 <template><view><view class"bgpart"><canvas class"canvas-wrap" canvas-id"canvasID" type"2d"></canvas…

GPT3.5的PPO目标函数怎么来的:From PPO to PPO-ptx

给定当前优化的大模型 π \pi π&#xff0c;以及SFT模型 π S F T \pi_{SFT} πSFT​ 原始优化目标为: max ⁡ E ( s , a ) ∼ R L [ π ( s , a ) π S F T ( s , a ) A π S F T ( s , a ) ] \max E_{(s,a)\sim RL}[\frac{\pi(s,a)}{\pi_{SFT}(s,a)}A^{\pi_{SFT}}(s,a)] m…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 03:强化你的子系统

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

windows无法完成格式化

方法. 使用CMD格式化 请将U盘连接到电脑&#xff0c;并确保电脑能够正常识别。 1. 在搜索框中输入“命令提示符”。在左侧结果中的“命令提示符”上点击右键&#xff0c;选择“以管理员身份运行”。 2. 在新窗口中&#xff0c;键入“diskpart”并按“回车”&#xff0c;然后…

如何通过小猪APP分发轻松实现Web封装APP

你有没有想过将你的网站或者Web应用变成一个真正的APP&#xff1f;这听起来可能有点复杂&#xff0c;但其实在今天的技术环境下&#xff0c;这已经变得非常简单了。特别是有了像小猪APP分发这样的工具&#xff0c;你可以轻松地将你的Web应用封装成一个APP。 为什么要将Web应用封…

Golang | Leetcode Golang题解之第164题最大间距

题目&#xff1a; 题解&#xff1a; type pair struct{ min, max int }func maximumGap(nums []int) (ans int) {n : len(nums)if n < 2 {return}minVal : min(nums...)maxVal : max(nums...)d : max(1, (maxVal-minVal)/(n-1))bucketSize : (maxVal-minVal)/d 1// 存储 (…

如何在不丢失数据的情况下解锁安卓手机密码

手机是我们生活中必不可少的工具&#xff0c;可以帮助我们与朋友和家人保持联系&#xff0c;了解最新消息&#xff0c;甚至经营我们的业务。然而&#xff0c;当我们在 Android 手机或 iPhone 上设置密码时&#xff0c;我们经常会忘记密码&#xff0c;或者根本没有设置密码。当这…

安卓多媒体(音频录播、传统摄制、增强摄制)

本章介绍App开发常用的一些多媒体处理技术&#xff0c;主要包括&#xff1a;如何录制和播放音频&#xff0c;如何使用传统相机拍照和录像&#xff0c;如何截取视频画面&#xff0c;如何使用增强相机拍照和录像。 音频录播 本节介绍Android对音频的录播操作&#xff0c;内容包…

SpringBoot3整合SpringDoc实现在线接口文档

写在前面 在现目前项目开发中&#xff0c;一般都是前后端分离项目。前端小姐姐负责开发前端&#xff0c;苦逼的我们负责后端开发 事实是一个人全干&#xff0c;在这过程中编写接口文档就显得尤为重要了。然而作为一个程序员&#xff0c;最怕的莫过于自己写文档和别人不写文档…

c函数/2024/6/17

1.递归计算0--n的和 #include <stdio.h> int sum(int n);//递归求和函数 int main(int argc, const char *argv[]) {//(2)递归计算0--n的和int n0;printf("请输入n的值为:");scanf("%d",&n);printf("0--n的和为:%d",sum(n));return 0…

AI早班车

全球AI新闻速递 1.国内团队制作AI短片《凤鸣山海》亮相北京电影节 国内团队制作AI短片《凤鸣山海》亮相北京电影节“光影未来”电影科技单元。独特的中国玄幻题材&#xff0c;朱雀、玄武、白虎、青龙&#xff0c;四大神兽栩栩如生 2.字节跳动拒绝出售TikTok&#xff0c;如果败…