一张图读懂异步编程模型是如何运作的

439次阅读  |  发布于10月以前

常言道,一图胜千言,我深以为然。正因如此,我偏爱用技术图解来阐释各类概念。最近在研究异步编程,找到了一张图片,它讲述了.NET 中 async/await 是如何运作的。

这张图展示了在涉及 I/O 操作时,.NET 异步编程模型如何运作,特别是在使用 IOCP 模型时任务和状态机如何相互作用。这种模型在处理高性能 I/O 操作时非常重要,如网络通信或文件 I/O,它允许应用程序有效地管理多个并发 I/O 操作,同时保持高响应性和高效率。

  1. IOCP 线程阻塞等待:IOCP 是一种用于高效处理多个 I/O 操作的机制。在使用 IOCP 时,有特定的线程(称为 IOCP 线程)在等待 I/O 操作的完成通知。这些线程不会执行其他工作,而是专门用于处理完成的 I/O 操作。
  2. 发起异步 I/O 操作
    • 打开设备和绑定到 IOCP:当一个工作线程调用例如 DoAsync 这样的方法时,它会“打开”一个设备(如文件、网络连接等),并将该设备“绑定”到 IOCP。这意味着当该设备的 I/O 操作完成时,相关的通知会被发送到 IOCP。
    • 开始重叠 I/O 和状态机创建:接着,工作线程启动一个重叠(即异步)的 I/O 操作。同时,为了管理这个异步操作的各个阶段,创建了一个状态机。此外,此操作返回一个 Task 对象,用于代表这个异步操作。
  3. I/O 操作完成:当 I/O 操作实际完成时(如数据已经从网络读取或写入文件),IOCP 会收到一个完成信号。
  4. IOCP 信号触发:IOCP 收到完成信号后,会从其等待队列中选择一个线程来处理这个通知。
  5. 状态机和任务结果设置
    • 执行状态机:被唤醒的 IOCP 线程运行之前创建的状态机代码,这部分代码负责处理 I/O 操作的完成。
    • 设置任务结果:状态机还负责设置与 I/O 操作相关联的 Task 的结果。这可能涉及到标记任务为成功完成或处理任何在 I/O 操作中发生的错误。
    • 决定续作执行策略:状态机还需要决定如何执行与任务相关联的续作。这可能包括直接在当前线程内联执行、使用特定的 SynchronizationContext(例如在 UI 线程上执行),或者使用自定义的 TaskScheduler 来安排续作的执行。

需要注意的是,在 Linux 系统中,我们使用 epoll 机制来代替 IOCPs。这里有专门的 epoll 线程负责监听事件,并把后续操作安排给工作线程执行(这里不会进行内联操作)。

图片出处:https://tooslowexception.com/net-asyncawait-in-a-single-picture/

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8