programación - tareas paralelas c#
Programación asíncrona APM vs EAP (3)
¿Cuál es realmente la diferencia entre el modelo de programación asíncrono y el patrón asincrónico basado en eventos ?
¿Qué enfoque de uso y cuándo?
Desde el 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 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 "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 de BCL IO y WCF, principalmente en operaciones de bajo nivel no cancelables (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 qué implementar (y se está limitando deliberadamente a estos dos), supongo que todo se reduce a lo que está haciendo o no.
Desde el código de cliente POV no siempre se puede elegir. Probablemente sea mejor usar las tareas de C # 4.5; si puedes, pueden trabajar con cualquiera de los mecanismos asíncronos más antiguos a través de envoltorios.
En el artículo de MSDN "Decidir cuándo implementar el patrón asíncrono basado en eventos" se ofrece una respuesta completa.
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"
El Modelo de programación asíncrono ( APM ) es el modelo que se ve con los BeginMethod(...)
y EndMethod(...)
.
Por ejemplo, aquí hay un Socket
usa la implementación de APM :
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 patrón asíncrono basado en eventos ( EAP ) es el modelo que se ve con los MethodAsync(...)
y CancelAsync(...)
. Normalmente hay un evento Completed
BackgroundWorker
es un buen ejemplo de este patrón.
A partir de C # 4.5 , ambos han sido reemplazados por el patrón async/await
, que utiliza la biblioteca de paralelismo de tareas ( TPL ). Los verá marcados con Async
después del nombre del método y, por lo general, devuelven una Task
o Task<TResult>
. Si puede apuntar a .NET 4.5, definitivamente debería usar este patrón sobre el diseño de APM o EAP.
Por ejemplo, al 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();
}
}