Що таке AsyncCallback?


79

У чому користь AsyncCallback і чому ми повинні його використовувати?

Відповіді:


143

Коли 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);
}

1
Чи є спосіб зробити це так, щоб CompleteRead була нестатичною функцією?
greggorob64

1
Так, ви можете зробити як екземпляри TestCallbackAPM, так і CompleteRead.
SO Користувач

32

Подумайте про це так. У вас є кілька операцій, які ви хотіли б виконувати паралельно. Ви могли б увімкнути це за допомогою потоків, які виконуються асинхронно. Це механізм пожежі та забуття.

Але в деяких ситуаціях потрібен механізм, за допомогою якого ви можете спрацьовувати і забувати, але про завершення операції потрібне повідомлення. Для цього ви б використали асинхронний зворотний виклик.

Операція є асинхронною, але передзвонить вам, коли операція завершиться. Перевага цього полягає в тому, що вам не доведеться чекати на операцію, поки вона не завершиться. Ви можете виконувати інші операції, а отже, ваш потік не заблокований.

Прикладом цього може бути фонова передача великого файлу. Поки передача триває, ви насправді не хочете заблокувати користувача робити інші операції. Після того, як передача буде завершена, процес передзвонить вам за допомогою асинхронного методу, де ви, ймовірно, зможете відкрити вікно повідомлення з написом "Перенесення завершено".


4

AsyncCallbacks використовуються для вказівки функції, яку потрібно викликати при завершенні асинхронної операції. Наприклад, якщо ви виконували операцію вводу-виводу, ви б викликали BeginRead у потоці та передавали делегат AsyncCAllback. Функція буде викликана, коли операція зчитування завершиться.

Для отримання додаткової інформації див.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.