首页 > 编程语言 >C#语言中的Async/await最佳实践

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

时间:2024-06-19 11:27:59浏览次数:13  
标签:异步 C# await ConfigureAwait 关键字 线程 UI Async

自从 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 应用程序中没有多大用处。

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

标签:异步,C#,await,ConfigureAwait,关键字,线程,UI,Async
From: https://blog.csdn.net/2401_82584055/article/details/139746342

相关文章

  • C#/.Net 中的多线程介绍和最佳实践
    I/引言计算机中的线程CPU调度程序和时间切片进程和线程并发和并行性异步与多线程在C中使用多线程的好处#II线程C语言#线程生命周期创建、启动和暂停线程加入中止中断线程取消:停止线程的更好方法III/线程问题死锁和争用条件使用Join和LocksAutoRese......
  • 如何使用csproj构建C#源代码组件NuGet包?
    一般我们构建传统的NuGet包,都是打包和分发dll程序集文件。至于打包和分发C#源代码文件的做法,比较少见。那么这种打包源代码文件的做法,有什么优点和缺点呢?优点:方便阅读源代码。方便断点调试。减少Assembly程序集模块加载个数。更利于发布期间的剪裁(PublishTrimmed选项)。......
  • 如何使用csproj构建C#源代码组件NuGet包?
    一般我们构建传统的NuGet包,都是打包和分发dll程序集文件。至于打包和分发C#源代码文件的做法,比较少见。那么这种打包源代码文件的做法,有什么优点和缺点呢?优点:方便阅读源代码。方便断点调试。减少Assembly程序集模块加载个数。更利于发布期间的剪裁(PublishTrimmed选项)。......
  • 【CS.SE】从源码到实践:探索日常对话的生成性语音模型ChatTTS
    文章目录1项目介绍1.1功能与特色2技术分析2.1模型架构3项目实践3.1快速上手4项目总结ReferencesGitcode上有许多优秀的开源项目,今天我们要介绍的是一个令人耳目一新的项目——ChatTTS。ChatTTS是一个基于深度学习的文本转语音(TTS)系统,它的目标是通过先进......
  • .NET C# 八股文 代码阅读(一)
    .NETC#八股文代码阅读(一)目录.NETC#八股文代码阅读(一)1两种获10000个数的方式,哪种效率更高?为什么?2请说出以下代码AB谁先打印,AB打印的值分别为多少?3关于值类型与引用类型、装箱与拆箱,以下代码会输出什么?4关于变量作用域,以下代码会输出什么?1两种获10000个数......
  • 如何使用csproj构建C#源代码组件NuGet包?
    一般我们构建传统的NuGet包,都是打包和分发dll程序集文件。至于打包和分发C#源代码文件的做法,比较少见。那么这种打包源代码文件的做法,有什么优点和缺点呢?优点:方便阅读源代码。方便断点调试。减少Assembly程序集模块加载个数。更利于发布期间的剪裁(PublishTrimmed选项)。......
  • 如何使用csproj构建C#源代码组件NuGet包?
    一般我们构建传统的NuGet包,都是打包和分发dll程序集文件。至于打包和分发C#源代码文件的做法,比较少见。那么这种打包源代码文件的做法,有什么优点和缺点呢?优点:方便阅读源代码。方便断点调试。减少Assembly程序集模块加载个数。更利于发布期间的剪裁(PublishTrimmed选项)。......
  • 如何使用csproj构建C#源代码组件NuGet包?
    一般我们构建传统的NuGet包,都是打包和分发dll程序集文件。至于打包和分发C#源代码文件的做法,比较少见。那么这种打包源代码文件的做法,有什么优点和缺点呢?优点:方便阅读源代码。方便断点调试。减少Assembly程序集模块加载个数。更利于发布期间的剪裁(PublishTrimmed选项)。......
  • 【信息学奥赛】CSP-J/S初赛03 计算机网络与编程语言分类
    第1节计算机网络基础1.1网络的定义所谓计算机网络,就是利用通信线路和设备,把分布在不同地理位置上的多台计算机连接起来。计算机网络是现代通信技术与计算机技术相结合的产物。网络中计算机与计算机之间的通信依靠协议进行。协议是计算机收、发数据的规则。TCP/IP:用于......
  • 如何使用csproj构建C#源代码组件NuGet包?
    一般我们构建传统的NuGet包,都是打包和分发dll程序集文件。至于打包和分发C#源代码文件的做法,比较少见。那么这种打包源代码文件的做法,有什么优点和缺点呢?优点:方便阅读源代码。方便断点调试。减少Assembly程序集模块加载个数。更利于发布期间的剪裁(PublishTrimmed选项)。......