2012-06-30 61 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