1. ホーム
  2. c#

[解決済み] AsyncCallbackとは何ですか?

2023-05-28 10:13:14

質問

AsyncCallbackの用途と、それを使用する理由は何ですか?

どのように解決するのですか?

このとき async メソッドが処理を終了すると AsyncCallback メソッドが自動的に呼び出され、そこで後処理文が実行されます。このテクニックでは async スレッドが完了するのを待つ必要はありません。

ここで、もう少し説明すると Async コールバックの使用法です。

コールバックのモデルです。 コールバックモデルでは、コールバックするメソッドを指定し、呼び出しを完了するためにコールバックメソッドに必要な状態を含めることが必要です。コールバックモデルは次の例で見ることができます。

static byte[] buffer = new byte[100];

static void TestCallbackAPM()
{
    string filename = System.IO.Path.Combine (System.Environment.CurrentDirectory, "mfc71.pdb");

    FileStream strm = new FileStream(filename,
        FileMode.Open, FileAccess.Read, FileShare.Read, 1024,
        FileOptions.Asynchronous);

    // Make the asynchronous call
    IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length,
        new AsyncCallback(CompleteRead), strm);
}

このモデルでは、新しい AsyncCallback デリゲートを作成し、操作の完了時に (別のスレッドで) 呼び出すメソッドを指定しています。さらに、呼び出しの状態として必要となる可能性のあるオブジェクトを指定しています。この例では、ストリームオブジェクトを送信しています。 EndRead を呼び出してストリームを閉じる必要があるため、ストリーム・オブジェクトを送信しています。

最後に呼び出されるように作成したメソッドは以下のようなものになります。

static void CompleteRead(IAsyncResult result)
{
    Console.WriteLine("Read Completed");

    FileStream strm = (FileStream) result.AsyncState;

    // Finished, so we can call EndRead and it will return without blocking
    int numBytes = strm.EndRead(result);

    // Don't forget to close the stream
    strm.Close();

    Console.WriteLine("Read {0} Bytes", numBytes);
    Console.WriteLine(BitConverter.ToString(buffer));
}

その他のテクニックは 完了するまで待つ ポーリング .

待機型モデル wait-until-done モデルでは、非同期呼び出しを開始し、他の作業を実行することができます。他の作業が完了したら、呼び出しを終了しようとすることができ、非同期呼び出しが完了するまでブロックされます。

// Make the asynchronous call
strm.Read(buffer, 0, buffer.Length);
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null);

// Do some work here while you wait

// Calling EndRead will block until the Async work is complete
int numBytes = strm.EndRead(result);

あるいは、ウェイトハンドルを使うこともできます。

result.AsyncWaitHandle.WaitOne();

ポーリングモデル ポーリング方法は似ていますが、例外として、このコードは IAsyncResult が完了したかどうかを確認するためにポーリングするという点が異なります。

// Make the asynchronous call
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null);

// Poll testing to see if complete
while (!result.IsCompleted)
{
    // Do more work here if the call isn't complete
    Thread.Sleep(100);
}