Qual è la differenza effettiva tra Modello di programmazione asincrono e Modello asincrono basato su evento?programmazione asincrona APM vs EAP
Quale approccio usare e quando?
Qual è la differenza effettiva tra Modello di programmazione asincrono e Modello asincrono basato su evento?programmazione asincrona APM vs EAP
Quale approccio usare e quando?
Il asincrono modello di programmazione (APM) è il modello che vedi con BeginMethod(...)
e EndMethod(...)
coppie.
Per esempio ecco un Socket
utilizzando il APM implementazione:
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);
}
}
Il basata sugli eventi asincrono modello (EAP) è il modello che vedi con MethodAsync(...)
e CancelAsync(...)
coppie. Di solito c'è un evento Completed
. BackgroundWorker
è un buon esempio di questo modello.
A partire dal C# 4.5, entrambi sono stati sostituiti dal modello async/await
, che sta utilizzando il Task Parallelismo Biblioteca (TPL). Li vedrai contrassegnati con Async
dopo il nome del metodo e di solito restituendo un attendibileTask
o Task<TResult>
. Se si è in grado di utilizzare .NET 4.5 come destinazione, è consigliabile utilizzare questo schema sulla progettazione APM o EAP.
Per esempio, la compressione di un (potenzialmente elevato) file in modo asincrono:
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();
}
}
Dal codice del client POV:
EAP: Si imposta un gestore di eventi per un evento il cui nome termina in "Completato "quindi chiama un metodo il cui nome termina con" Async ". A volte puoi chiamare un metodo con "Annulla" nel suo nome che potrebbe cancellarlo.
APM: si chiama un metodo il cui nome inizia con "Inizia", quindi esegue il polling del risultato o riceve una richiamata, quindi chiama un metodo che inizia con "Fine".
Per quanto ne so, l'APM è implementato su gran parte delle classi BCL IO e WCF, principalmente operazioni non modificabili di livello inferiore (come nel caso in cui si annulla semplicemente ignorare il risultato). EAP si trova su classi di livello più alto, ad esempio per scaricare un file, dove ci sono più passaggi e qualche tipo di comportamento di cancellazione significativo.
Quindi, se è necessario scegliere quale implementare (e si sta deliberatamente limitando te stesso a questi due), suppongo che ciò che stai facendo sia cancellabile o meno.
Dal codice client POV non si ottiene sempre una scelta. Probabilmente è meglio usare i task C# 4.5 se puoi, possono lavorare con i meccanismi asincroni più vecchi tramite i wrapper.
Buon punto a proposito della mancanza di funzionalità di cancellazione sul design __APM__. Come detto, 'Task.Factory.FromAsync (...)' è il wrapper C# 4.5 per trasformare lo stile __APM__ nel pattern __TPL__. Vedi: – Erik
Mi spiace, combattendo con i commenti SO qui (perché la maggior parte dei loro formati di link "supportati" __NOT__ funzionano nei commenti)? [TPL e Traditional .NET Asynchronous Programming] (http://msdn.microsoft.com/en-us/library/dd997423.aspx) – Erik
Una risposta esaustiva è fornita dall'articolo MSDN "Deciding When to Implement the Event-based Asynchronous Pattern".
L'idea principale di questo articolo (e risposta breve alla tua domanda) suona come "Generare il modello basato su eventi di default, con la possibilità di generare il modello IAsyncResult"
Il [MSDN docs] (http: //msdn.microsoft.com/en-us/library/jj152938.aspx) copre abbastanza bene. –
Ottimo articolo! Sicuramente aggiunto alla mia raccolta di segnalibri. – Erik