AsyncCallbackの使用とは何ですか?なぜ使用する必要がありますか?
async
メソッドが処理を終了すると、AsyncCallback
メソッドが自動的に呼び出され、後処理ステートメントを実行できます。この手法を使用すると、async
スレッドが完了するのをポーリングまたは待機する必要がありません。
Async
コールバックの使用法の詳細は次のとおりです。
Callback Model:コールバックモデルでは、コールバックするメソッドを指定し、コールを完了するために必要な状態をコールバックメソッドに含める必要があります。コールバックモデルは、次の例で見ることができます。
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およびPollingです。
Wait-Until-Done Model 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);
}
このように考えてください。並行して実行したい操作がいくつかあります。これを有効にするには、非同期で実行されるスレッドを使用します。これは、火と忘却のメカニズムです。
しかし、状況によっては、起動して忘れることができるが、操作の完了時に通知が必要なメカニズムが必要です。これには、非同期コールバックを使用します。
操作は非同期ですが、操作が完了するとコールバックされます。この利点は、完了するまで操作を待つ必要がないことです。他の操作を自由に実行できるため、スレッドはブロックされません。
この例は、大きなファイルのバックグラウンド転送です。転送が進行している間、ユーザーが他の操作を実行するのを本当にブロックしたくありません。転送が完了すると、プロセスは非同期メソッドを呼び出します。このメソッドでは、「転送完了」というメッセージボックスをポップアップ表示できます。
AsyncCallbacksは、非同期操作が完了したときに呼び出す関数を指定するために使用されます。たとえば、IO操作を実行している場合、ストリームでBeginReadを呼び出し、AsyncCAllbackデリゲートを渡します。読み取り操作が完了すると、関数が呼び出されます。
詳細については、以下を参照してください。