1. ホーム
  2. c#

[解決済み] 非同期メソッドの完了を待つには?

2022-04-24 19:11:49

質問

USB HIDクラスのデバイスにデータを転送するWinFormsアプリケーションを書いています。 私のアプリケーションは、優れたGeneric HIDライブラリv6.0を使用しており、それは次の場所で見つけることができます。 こちら . 簡単に言うと、デバイスにデータを書き込む必要があるときに、このコードが呼び出されるのです。

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()

残念ながら、私は.NET 4.5の新しいasync/awaitテクノロジーの仕組みにあまり詳しくありません。 以前、awaitキーワードについて少し読みましたが、RequestToGetInputReport()内のGetInputReportViaInterruptTransfer()への呼び出しが待機するような印象を受けました(そして多分そうでしょう)しかし、私がほとんどすぐにwhileループに再入力するようなのでRequestToGetInputReport()への呼び出し自体は待っていないように見えますか。

どなたか、私が見ている動作を明確にすることができますか?

解決方法は?

避ける 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();
}