gpt4 book ai didi

.net - 我对 async/await、它的工作原理及其优点的理解是否正确?

转载 作者:行者123 更新时间:2023-12-02 14:50:59 24 4
gpt4 key购买 nike

我曾在几次场合表达过我对 async/await 的理解,经常会引发一些关于我是否正确的争论。如果有人能够证实或否认我的理解,并消除任何误解,这样我就不会传播错误信息,我将非常感激。

高层理解

async/await 是编写异步代码时避免回调 hell 的一种方法。正在执行异步方法的线程在遇到 await 时将返回线程池,并在等待的操作完成后继续执行。

低级理解

JIT 会将异步方法分成围绕 await 点的离散部分,允许重新进入该方法并保留方法的状态。在幕后,这涉及某种状态机。

与并发的关系

async/await 并不意味着任何类型的并发。使用 async/await 编写的应用程序可以完全是单线程的,同时仍然可以获得所有好处,就像 Node.js 所做的那样,尽管有回调。与 Node.js 不同,.NET 是多线程的,因此通过使用 async/await,您可以在不使用回调的情况下获得非阻塞 IO 的优势,同时还可以拥有多个线程执行。

好处

async/await 在等待 IO 完成时释放线程去做其他事情。它还可以与 TPL 结合使用在多个线程上或在 UI 线程之外执行 CPU 密集型工作。

为了从非阻塞 IO 中受益,异步方法需要构建在 API 之上,实际上利用最终由操作系统提供的非阻塞 IO。

滥用

这是我理解中最大的争议点。很多人认为将阻塞操作包装在 Task 中并使用 async/await 会带来性能提升。通过创建一个额外的线程来处理操作,将原始线程返回到线程池,然后在任务完成后恢复原始方法,所发生的只是不必要的上下文切换,而没有真正释放线程去做其他工作。虽然这不像 TPL 那样是对 async/await 的误用,但这种心态似乎源于对 async 的误解/等待

最佳答案

这非常正确。

但有一些注意事项:

  • 开始执行异步方法的线程是调用者的线程,它可能是也可能不是 ThreadPool 线程。
  • 如果到达等待,但可等待(通常是任务)已经完成,线程将继续同步执行方法的其余部分。
  • 恢复运行该方法的线程通常是 ThreadPool 线程,但这取决于 SyncrhonizationContextTaskScheduler
  • 这里不涉及 JIT(不比平时更多)。编译器是将异步方法转换为状态机的编译器。您可以通过 this TryRoslyn example 看到这一点.
  • 确实,async-await 并不一定意味着并发,因为它可能是单线程的。但是,通过同时启动和等待多个异步操作,即使只有一个线程,它仍然可以并发。
  • async-await 和 TPL 并不是完全独立的部分。 async-await 构建在 TPL 之上。这就是为什么它被称为基于任务的异步模式。
  • 虽然大多数真正的异步操作都是 I/O,但并非全部都是。您通常还可以使用 Task.Delay 进行异步延迟,或使用 SemaphoreSlim.WaitAsync 等异步同步结构。

关于.net - 我对 async/await、它的工作原理及其优点的理解是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31899407/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com