конструктор - c# дождаться выполнения асинхронного метода



Как дождаться завершения асинхронного метода? (3)

Я пишу приложение WinForms, которое передает данные на USB-устройство класса HID. В моем приложении используется отличная универсальная 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();
}

Для чего это стоит, декларация для GetInputReportViaInterruptTransfer () выглядит так:

internal async Task<int> GetInputReportViaInterruptTransfer()

К сожалению, я не очень хорошо разбираюсь в работе новых технологий async / await в .NET 4.5. Я немного читал ранее о ключевом слове «Ожидание», и это создавало впечатление, что вызов GetInputReportViaInterruptTransfer () внутри RequestToGetInputReport () будет ждать (и, возможно, это так?), Но это не похоже на вызов RequestToGetInputReport () сам ждет, потому что я, кажется, сразу возвращаюсь в цикл while почти сразу?

Может ли кто-нибудь уточнить поведение, которое я вижу?


Избегайте async void . Пусть ваши методы возвращают Task вместо void . Тогда вы можете их await .

Как это:

private async Task 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
        await RequestToGetInputReport();
    }
}

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

Лучшее решение для ожидания AsynMethod до завершения задачи

var result = Task.Run(async() => { return await yourAsyncMethod(); }).Result;

Следующий фрагмент показывает способ обеспечения ожидаемого метода до того, как он вернется к вызывающему. ОДНАКО, я бы не сказал, что это хорошая практика. Пожалуйста, отредактируйте мой ответ с объяснениями, если вы думаете иначе.

public async Task AnAsyncMethodThatCompletes()
{
    await SomeAsyncMethod();
    DoSomeMoreStuff();
    await Task.Factory.StartNew(() => { }); // <-- This line here, at the end
}

await AnAsyncMethodThatCompletes();
Console.WriteLine("AnAsyncMethodThatCompletes() completed.")




async-await