【问题标题】:C# async and await - what is a compelling use case? [closed]C# async 和 await - 什么是引人注目的用例? [关闭]
【发布时间】:2019-01-02 20:56:08
【问题描述】:

我过去曾在 C# 中详细查看过 asyncawait,包括查看我在该主题上找到的所有 StackOverflow 问题,但我从未实施过asyncawait 在代码中,原因如下:

  • 我对主要性能优势的理解是,如果您有一个长时间运行的进程,然后是执行耗时的逻辑,然后是消耗由 first 长时间运行的进程返回的内容.我从来没有遇到过这种情况。我遇到过在初始长时间运行的进程和依赖于长时间运行的进程之间存在最小逻辑的场景,引入await 并没有足够的吸引力足够async 用于轻微的性能节省。引入异步调用会在执行顺序方面引入一定程度的复杂性,而对于小的性能提升,我一直觉得这种复杂性不值得
  • 它只会让 async 代码更容易编写,而且我通常在前端使用 JavaScript(通常是 Angular)来完成我所有的异步工作,所以我从来没有识别出一个 令人信服需要在后端进行异步工作

我经常在工作面试中被问到我对asyncawait 的理解,我可以回答这个问题,但是我从未完全了解或目睹过这样一个案例: asyncawait 显然是一段代码中更可取的模式。由于我没有使用asyncawait 的习惯,因此我希望能够识别何时需要使用asyncawait 的用例或场景。在系统中通常实现的引人注目的用例或场景的一个很好的实际示例是什么?

【问题讨论】:

标签: c# asynchronous async-await


【解决方案1】:

一个很好的例子是将数据保存到文件或数据库中。

这是一个例子:

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        string StartDirectory = @"c:\Users\exampleuser\start";
        string EndDirectory = @"c:\Users\exampleuser\end";

        foreach (string filename in Directory.EnumerateFiles(StartDirectory))
        {
            using (FileStream SourceStream = File.Open(filename, FileMode.Open))
            {
                using (FileStream DestinationStream = File.Create(EndDirectory + filename.Substring(filename.LastIndexOf('\\'))))
                {
                    await SourceStream.CopyToAsync(DestinationStream);
                }
            }
        }
    }

直接由 Microsoft 实现:https://docs.microsoft.com/en-us/dotnet/standard/io/asynchronous-file-i-o

【讨论】:

    【解决方案2】:

    好吧,我认为人们似乎在这里忘记了异步 I/O 与 I/O completion ports (IOCP) 一起使用时,async/await 很好地封装了,不使用昂贵的线程,因此允许每秒执行更多的 I/O 操作,而线程开销最小。见There Is No Thread

    overlapped I/O 虽然是异步的,但确实需要线程来等待 Windows 文件句柄,因此它不如 IOCP 高效

    所有 I/O 本质上都是异步的,像 Stream.Read() 这样的同步方法是一种逃避

    这是不正确的。还有阻塞 I/O。您很快就会知道您正在使用阻塞 I/O,因为您的线程使用量猛增。例如在 HAPIHL7 .NET 库中阻止网络 I/O 操作的 I/O

    【讨论】:

    【解决方案3】:

    感谢@David Haim 提示您阅读异步 IO - https://en.wikipedia.org/wiki/Asynchronous_I/O。关键是,在一个操作将执行多次的系统中,计算异步/等待可能有显着的累积性能改进是很重要的(即使它只产生很小的性能在方法级别增加)

    我目前正在进行的项目是一个很好的例子,说明了需要实施async/await。该系统与直接连接到 PC 的环境测量设备(例如天气监测仪器)进行通信,以频繁地定期轮询。由于这种轮询是密集的并且可能是大容量的,因此执行任何不依赖于返回数据的操作(尤其是在使用轮询值期间)所节省的性能显着增加。严格来说,系统中的这种轮询类型意味着需要并行性,并且除了使用asyncawait 操作之外,还可能需要考虑性能。

    一般来说,任何高容量和/或高频率的实时数据轮询都可能构成代码中 async/await somewhere 的一个引人注目的用例。

    【讨论】:

    • 轮询不会自动异步。您在这里谈论的是并行性。
    猜你喜欢
    • 2019-05-29
    • 2019-03-21
    • 2018-01-05
    • 2014-12-06
    • 2023-03-27
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多