¿Qué es AsyncCallback?

Respuestas:

143

Cuando el asyncmétodo termina el procesamiento, AsyncCallbackse llama automáticamente al método, donde se pueden ejecutar declaraciones de procesamiento posterior. Con esta técnica no es necesario sondear ni esperar asynca que se complete el hilo.

Aquí hay una explicación más sobre el Asyncuso de la devolución de llamada:

Modelo de devolución de llamada : el modelo de devolución de llamada requiere que especifiquemos un método para devolver la llamada e incluimos cualquier estado que necesitemos en el método de devolución de llamada para completar la llamada. El modelo de devolución de llamada se puede ver en el siguiente ejemplo:

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);
}

En este modelo, estamos creando un nuevo AsyncCallbackdelegado, especificando un método para llamar (en otro hilo) cuando se completa la operación. Además, estamos especificando algún objeto que podríamos necesitar como estado de la llamada. Para este ejemplo, estamos enviando el objeto de flujo porque necesitaremos llamar EndReady cerrar el flujo.

El método que creamos para ser llamado al final de la llamada se vería así:

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));
}

Otras técnicas son Esperar hasta terminar y Sondeo .

Modelo de esperar hasta terminar El modelo de esperar hasta terminar le permite iniciar la llamada asincrónica y realizar otro trabajo. Una vez que se realiza el otro trabajo, puede intentar finalizar la llamada y se bloqueará hasta que se complete la llamada asincrónica.

// 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);

O puede usar asas de espera.

result.AsyncWaitHandle.WaitOne();

Modelo de sondeo El método de sondeo es similar, con la excepción de que el código sondeará el IAsyncResultpara ver si se ha completado.

// 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 Usuario
fuente
1
¿Hay alguna forma de hacer esto para que CompleteRead sea una función no estática?
greggorob64
1
Sí, puede crear métodos de instancia tanto TestCallbackAPM como CompleteRead.
SO Usuario
32

Piénsalo de esta manera. Tiene algunas operaciones que le gustaría ejecutar en paralelo. Puede habilitar esto mediante el uso de subprocesos que se ejecutan de forma asincrónica. Este es un mecanismo de fuego y olvido.

Pero algunas situaciones requieren un mecanismo en el que pueda disparar y olvidar, pero necesita una notificación cuando se complete la operación. Para esto, usaría una devolución de llamada asíncrona.

La operación es asincrónica, pero le devuelve la llamada cuando finaliza. La ventaja de esto es que no tiene que esperar a que la operación se complete. Eres libre de ejecutar otras operaciones y, por lo tanto, tu hilo no está bloqueado.

Un ejemplo de esto sería una transferencia en segundo plano de un archivo grande. Mientras la transferencia está en progreso, realmente no desea bloquear al usuario para que no realice otras operaciones. Una vez que se complete la transferencia, el proceso le devolverá la llamada mediante un método asíncrono, donde probablemente pueda abrir un cuadro de mensaje que diga "Transferencia completa".

bobbyalex
fuente
4

AsyncCallbacks se utilizan para especificar una función para llamar cuando se completa una operación asincrónica. Por ejemplo, si estuviera realizando una operación de E / S, llamaría a BeginRead en una secuencia y pasaría un delegado AsyncCAllback. La función se llamaría cuando se completara la operación de lectura.

Para más información, ver:

pesado
fuente