Что такое AsyncCallback?

79

Какая польза от AsyncCallback и почему мы должны его использовать?

RV.
источник

Ответы:

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);
}
SO Пользователь
источник
1
Есть ли способ сделать это, чтобы CompleteRead была нестатической функцией?
greggorob64
1
Да, вы можете использовать методы экземпляра TestCallbackAPM и CompleteRead.
SO User
32

Подумайте об этом так. У вас есть операции, которые вы хотите выполнять параллельно. Вы можете включить это, используя потоки, которые выполняются асинхронно. Это механизм «выстрелил и забыл».

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

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

Примером этого может быть фоновая передача большого файла. Пока выполняется передача, вы действительно не хотите запрещать пользователю выполнять другие операции. Как только передача будет завершена, процесс перезвонит вам асинхронным методом, где вы, вероятно, сможете вывести окно сообщения с надписью «Передача завершена».

боббиалекс
источник
4

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

Для получения дополнительной информации см .:

тяжелый
источник