c# - 如何等待异步方法完成?

标签 c# asynchronous async-await

我正在编写一个将数据传输到 USB HID 类设备的 WinForms 应用程序。我的应用程序使用了出色的通用 HID 库 v6.0,可以找到它 here .简而言之,当我需要向设备写入数据时,调用的代码如下:

private async void RequestToSendOutputReport(List<byte[]> byteArrays)
{
    foreach (byte[] b in byteArrays)
    {
        while (condition)
        {
            // we'll typically execute this code many times until the condition is no longer met
            Task t = SendOutputReportViaInterruptTransfer();
            await t;
        }

        // read some data from device; we need to wait for this to return
        RequestToGetInputReport();
    }
}

当我的代码退出 while 循环时,我需要从设备读取一些数据。但是,该设备无法立即响应,因此我需要等待此调用返回才能继续。由于目前存在,RequestToGetInputReport() 声明如下:

private async void RequestToGetInputReport()
{
    // lots of code prior to this
    int bytesRead = await GetInputReportViaInterruptTransfer();
}

就其值(value)而言,GetInputReportViaInterruptTransfer() 的声明如下所示:

internal async Task<int> GetInputReportViaInterruptTransfer()

不幸的是,我不太熟悉 .NET 4.5 中新的异步/等待技术的工作原理。我之前阅读了一些关于 await 关键字的内容,这给我的印象是在 RequestToGetInputReport() 内部调用 GetInputReportViaInterruptTransfer() 会等待(也许它会等待?)但它看起来不像是调用 RequestToGetInputReport()本身正在等待,因为我似乎几乎立即重新进入了 while 循环?

任何人都可以澄清我所看到的行为吗?

最佳答案

关于async最重要的事情要知道|和 await是那个await 等待关联的调用完成。什么await 如果操作已经完成,则立即同步返回操作结果,如果还没有完成,则安排继续执行 async 的剩余部分方法,然后将控制权返回给调用者。当异步操作完成时,预定的完成将执行。

问题标题中特定问题的答案是阻止 async方法的返回值(应该是 TaskTask<T> 类型)通过调用适当的 Wait方法:

public static async Task<Foo> GetFooAsync()
{
    // Start asynchronous operation(s) and return associated task.
    ...
}

public static Foo CallGetFooAsyncAndWaitOnResult()
{
    var task = GetFooAsync();
    task.Wait(); // Blocks current thread until GetFooAsync task completes
                 // For pedagogical use only: in general, don't do this!
    var result = task.Result;
    return result;
}

在此代码片段中,CallGetFooAsyncAndWaitOnResult是异步方法的同步包装器 GetFooAsync .但是,在大多数情况下要避免这种模式,因为它会在异步操作期间阻塞整个线程池线程。这是对 API 所公开的各种异步机制的低效使用,这些 API 竭力提供这些机制。

答案在 "await" doesn't wait for the completion of call对这些关键字有几个更详细的解释。

与此同时,@Stephen Cleary 关于 async void 的指导持有。关于原因的其他很好的解释可以在 http://www.tonicodes.net/blog/why-you-should-almost-never-write-void-asynchronous-methods/ 找到。和 https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.html

关于c# - 如何等待异步方法完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15149811/

相关文章:

c# - 使用 async/await 卡住 UI

c# - 使用 C# StreamReader 解析文本文件

c# - 可选参数和方法重载

c# - 分组可折叠导航控件 Windows 应用商店应用程序?

java - 将状态保存到 onPause() 中的文件需要太长时间

javascript - 使用 Promise.all() 实现 promise 时执行操作

c# - 保存到数据库需要太长时间

c# - 异步方法中的最后一次异步调用是否需要等待?

node.js - 如何使用带有 promise 的异步等待来获取结果?

c# - 多个异步/等待链接