2012-06-30 6 views
19

¿Qué es realmente la diferencia entre Modelo de programación asíncrona y Patrón asincrónico basado en eventos?programación asíncrona APM vs EAP

¿Qué enfoque utilizar y cuándo?

+2

El [MSDN docs] (http: //msdn.microsoft.com/en-us/library/jj152938.aspx) cubra esto bastante bien. –

+0

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

Respuesta

17

El asincrónica modelo de programación (APM ) es el modelo que se ve con BeginMethod(...) y EndMethod(...) pares.

Por ejemplo, aquí es una Socket utilizando el APM aplicació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); 
    } 
} 

El basada en eventos modelo asincrónico (EAP ) es el modelo que se ve con MethodAsync(...) y CancelAsync(...) pares. Generalmente hay un evento Completed. BackgroundWorker es un buen ejemplo de este patrón.

Como de C# 4.5, ambos han sido sustituidos por el patrón de async/await, que está utilizando el Tarea Paralelismo Biblioteca (TPL). Los verá marcados con Async después del nombre del método y generalmente devuelve Task o Task<TResult>. Si puede orientar a .NET 4.5, definitivamente debe usar este patrón sobre el diseño de APM o EAP.

Por ejemplo, la compresión de un (potencialmente grande) presentar 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(); 
    } 
} 
5

Desde el código de cliente POV:

EAP: Se configura un controlador de eventos para un evento cuyo nombre termina en "Completado "luego llama a un método cuyo nombre termina con" 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 "Comenzar", luego sondea su resultado o recibe una devolución de llamada, luego llama a un método que comienza con "Fin".

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

Así que si necesita elegir qué implementar (y se limita deliberadamente a estos dos) supongo que se trata de lo que se puede cancelar o no.

Desde el código de cliente POV no siempre se puede elegir. Probablemente sea mejor utilizar Tareas C# 4.5 si puede, pueden trabajar con cualquiera de los mecanismos asincrónicos más antiguos a través de envoltorios.

+2

Buen punto acerca de la falta de funcionalidad de cancelación en el diseño __APM__. También como se mencionó, 'Task.Factory.FromAsync (...)' es el contenedor C# 4.5 para convertir el estilo __APM__ en el patrón __TPL__. Ver: Erik

+0

Disculpe, peleando con los comentarios de SO aquí (¿por qué la mayoría de sus formatos de enlace "compatibles" __NOT__ funcionan en los comentarios)? [Programación asincrónica TPL y tradicional .NET] (http://msdn.microsoft.com/en-us/library/dd997423.aspx) – Erik

Cuestiones relacionadas