programación asíncrona APM vs EAP

¿Cuál es realmente la diferencia entre Modelo de programación asincrónica y Patrón asíncrono basado en eventos?

¿Qué enfoque utilizar y cuándo?

preguntado el 30 de junio de 12 a las 18:06

La Documentos de MSDN cubrir esto bastante bien. -

¡Buen artículo! Definitivamente agregado a mi colección de marcadores. -

3 Respuestas

La Modelo de programación asincrónica (APM) es el modelo que ves con BeginMethod(...) y EndMethod(...) pares.

Por ejemplo aquí hay un Socket usando el APM implementación:

 var socket = new Socket(AddressFamily.InterNetwork, 
                        SocketType.Stream, ProtocolType.Tcp);

 // ...

 socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, 
                     SocketFlags.None, ReceiveCallback, null);

 void ReceiveCallback(IAsyncResult result)
 {
   var bytesReceived = socket.EndReceive(result);

   if (bytesReceived > 0) { // Handle received data here. }

   if (socket.Connected)
   {
     // Keep receiving more data...
     socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, 
                         SocketFlags.None, ReceiveCallback, null);
   }
 }

La Patrón asincrónico basado en eventos (EAP) es el modelo que ves con MethodAsync(...) y CancelAsync(...) pares Suele haber un Completed evento. BackgroundWorker es un buen ejemplo de este patrón.

A partir del C # 4.5, ambos han sido reemplazados por el async/await patrón, que utiliza el Biblioteca de paralelismo de tareas (TPL). Los verás marcados con Async después del nombre del método y normalmente devuelve un aguardable Task or Task<TResult>. Si puede apuntar a .NET 4.5, definitivamente debe usar este patrón sobre el diseño APM o EAP.

Por ejemplo, comprimir un archivo (potencialmente grande) de forma asíncrona:

public static async Task CompressFileAsync(string inputFile, string outputFile)
{
  using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read))
  using (var outputStream = File.Create(outputFile))
  using (var deflateStream = new DeflateStream(outputStream, CompressionMode.Compress))
  {
    await inputStream.CopyToAsync(deflateStream);

    deflateStream.Close();
    outputStream.Close();
    inputStream.Close();
  }
}

Respondido el 14 de enero de 13 a las 23:01

Del código de cliente POV:

EAP: configura un controlador de eventos para un evento cuyo nombre termina en "Completado" y luego llama a un método cuyo nombre termina en "Async". A veces puede llamar a un método con "Cancelar" en su nombre que podría cancelarlo.

APM: llama a un método cuyo nombre comienza con "Begin", luego sondea su resultado o recibe una devolución de llamada, luego llama a un método que comienza con "End".

Por lo que sé de los dos, APM se implementa en la mayoría de las clases BCL IO y WCF, principalmente operaciones no cancelables de nivel inferior (como para cancelar, simplemente ignore el resultado). EAP se encuentra en clases de nivel más alto, es decir, para descargar un archivo, donde hay varios pasos y algún tipo de comportamiento de cancelación significativo.

Entonces, si necesita elegir cuál implementar (y se limita deliberadamente a estos dos), supongo que se debe a que lo que está haciendo es cancelable o no.

Desde el punto de vista del código de cliente no siempre se puede elegir. Probablemente sea mejor usar tareas de C# 4.5 si puede, pueden funcionar con cualquiera de los mecanismos asincrónicos más antiguos a través de contenedores.

Respondido el 14 de enero de 13 a las 23:01

Buen punto sobre la falta de funcionalidad de cancelación en el APM diseño. También como se mencionó, Task.Factory.FromAsync(...) es el contenedor de C# 4.5 para convertir APM estilo en el TPL patrón. Ver:msdn.microsoft.com/en-us/library/dd997423.aspx" title="TPL y programación asincrónica .NET tradicional"> - Erik

Lo siento, peleando con los comentarios SO aquí (¿por qué la mayoría de sus formatos de enlace "compatibles" NO trabajo en comentarios)? Programación asíncrona TPL y .NET tradicional - Erik

Se da una respuesta completa en el artículo de MSDN "Decidir cuándo implementar el patrón asíncrono basado en eventos".

La idea principal de este artículo (y una breve respuesta a su pregunta) suena como "Generar el patrón basado en eventos de forma predeterminada, con una opción para generar el patrón IAsyncResult".

Respondido el 10 de enero de 14 a las 08:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.