2012-06-30 63 views
19

异步编程模型基于事件的异步模式异步编程APM vs EAP

使用何种方法?

+2

的[MSDN文档(HTTP: //msdn.microsoft.com/en-us/library/jj152938.aspx)涵盖了这一点。 –

+0

伟大的文章!绝对添加到我的书签收藏中。 – Erik

回答

17

异步编程模型APM)是您与BeginMethod(...)EndMethod(...)对看到模型。

例如这里是一个Socket使用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); 
    } 
} 

基于事件的异步模式EAP)是您与MethodAsync(...)CancelAsync(...)对看模型。通常有一个Completed事件。 BackgroundWorker就是这种模式的一个很好的例子。

作为C#4.5,二者都被替换为async/await图案,这是使用的任务并行库TPL)。您会在方法名称后面看到它们标记为Async,并且通常返回等待TaskTask<TResult>。如果你能够以.NET 4.5为目标,你应该在APM或EAP设计中使用这种模式。

例如,压缩(潜在大)异步文件:

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

从客户端代码POV:

EAP:您设置的事件处理程序的事件,其名称中的“完成结束“然后调用名称以”异步“结尾的方法。您有时可以通过名称中的“取消”来调用可能会取消它的方法。

APM:您调用名称以“Begin”开头的方法,然后轮询其结果或接收回调,然后调用以“End”开头的方法。

据我所知,APM是在大多数BCL IO类和WCF中实现的,主要是低级别的不可删除操作(因为取消你只是忽略结果)。 EAP可以在更高级的类上找到,即下载文件,其中有多个步骤和某种有意义的取消行为。因此,如果您需要选择要执行的操作(并且您故意将自己限制为这两个操作),那么我认为它对您所做的操作是可以取消或不可以的。

从客户端代码POV你不总是得到一个选择。如果可以,最好使用C#4.5任务,他们可以通过包装器使用任何旧的异步机制。

+2

关于__APM__设计中缺少取消功能的好处。同样如前所述,'Task.Factory.FromAsync(...)'是将__APM__样式转换为__TPL__样式的C#4.5包装器。请参阅: Erik

+0

对不起,在这里与SO评论作斗争(为什么大多数他们的“支持”链接格式__NOT__在评论中工作)? [TPL和传统的.NET异步编程](http://msdn.microsoft.com/zh-cn/library/dd997423.aspx) – Erik