Когда метод 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));
}
Другие методы: Ожидание до завершения и Опрос .
Модель с ожиданием до завершения Модель с ожиданием до завершения позволяет запустить асинхронный вызов и выполнить другую работу. Как только другая работа будет завершена, вы можете попытаться завершить вызов, и он будет блокирован до завершения асинхронного вызова.
// 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);
}