2012-06-30 17 views
19

Czym właściwie jest różnica pomiędzy Asynchroniczny model programowania i Akryroniczny wzór oparty na zdarzeniach?programowanie asynchroniczne APM vs EAP

Jakie podejście do stosowania i kiedy?

+2

Sieć [MSDN docs] (http: //msdn.microsoft.com/en-us/library/jj152938.aspx) to całkiem dobrze. –

+0

Świetny artykuł! Zdecydowanie dodane do mojej kolekcji zakładek. – Erik

Odpowiedz

17

The asynchroniczny model programowania (APM) jest model widać z BeginMethod(...) i EndMethod(...) parach.

Na przykład o to Socket pomocą realizację 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); 
    } 
} 

zdarzeń oparte asynchroniczny Wzór (EAP) jest model widać z MethodAsync(...) i CancelAsync(...) parach. Zwykle zdarza się zdarzenie Completed. BackgroundWorker jest dobrym przykładem tego wzoru.

Na C 4,5, oba zostały zastąpione przez wzór async/await, który jest za pomocą Zadanie Równoległość Bibliotekę (OC). widać je zaznaczone Async po nazwie metody i zwykle zwrócenie awaitableTask lub Task<TResult>. Jeśli jesteś w stanie kierować na platformę .NET 4.5, zdecydowanie powinieneś używać tego wzorca nad projektem APM lub EAP.

Na przykład sprężanie (potencjalnie duża) plik asynchronicznie:

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

Z POV kodu klient:

EAP: skonfigurowaniu obsługi zdarzeń dla zdarzenia, którego nazwa kończy się na „Zakończony "następnie wywołaj metodę, której nazwa kończy się na" Async ". Czasami możesz wywołać metodę z "Anuluj" w nazwie, która może ją anulować.

APM: wywołać metodę, którego nazwa zaczyna się od „Rozpocznij”, a następnie sondować swój wynik lub odbierać wywołania zwrotnego, a następnie wywołać metodę, która zaczyna się od „Koniec”.

Z tego co wiem, APM jest implementowany w większości klas IO i WCF BCL, głównie w operacjach niecałkowitości niższego poziomu (w celu anulowania wystarczy zignorować wynik). Protokół EAP znajduje się w klasach o wyższym poziomie, tj. W celu pobrania pliku, w którym występuje wiele kroków i pewnego rodzaju znaczące anulowanie.

Więc jeśli trzeba wybrać do realizacji (i celowo ograniczając się do tych dwóch) Chyba ITS do tego, co robisz można rozwiązać, czy nie.

Z POV kodu klient nie zawsze wybór. Najlepiej jest użyć C# 4.5 Tasks, jeśli możesz, mogą pracować z dowolnym ze starszych mechanizmów asynchronicznych za pomocą wrapperów.

+2

Dobra uwaga na temat braku funkcji anulowania w projekcie __APM__. Jak już wspomniano, 'Task.Factory.FromAsync (...)' jest opakowaniem C# 4.5, służącym do przekształcania stylu __APM__ na wzór __TPL__. Zobacz: Erik

+0

Przepraszamy, walcząc z komentarzami SO tutaj (dlaczego większość ich "obsługiwanych" formatów linków __NOT__ działa w komentarzach)? [Programowanie asynchroniczne TPL i tradycyjne .NET] (http://msdn.microsoft.com/en-us/library/dd997423.aspx) – Erik