programmation asynchrone APM vs EAP

Quelle est la différence entre le modèle de programmation asynchrone et le modèle asychrone basé sur des événements ?

Quelle approche utiliser et quand?

Le modèle de programmation asynchrone ( APM ) est le modèle que vous voyez avec les BeginMethod(...) et EndMethod(...) .

Par exemple, voici un Socket utilisant l’implémentation 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); } } 

Le modèle asynchrone basé sur des événements ( EAP ) est le modèle que vous voyez avec les MethodAsync(...) et CancelAsync(...) . Il y a généralement un événement Completed . BackgroundWorker est un bon exemple de ce modèle.

À partir de C # 4.5 , les deux ont été remplacés par le modèle async/await , qui utilise la bibliothèque de parallélisme de tâches ( TPL ). Vous les verrez marqués Async après le nom de la méthode et renvoyant généralement une Task attente ou une Task . Si vous parvenez à cibler .NET 4.5, vous devez absolument utiliser ce modèle sur la conception APM ou EAP.

Par exemple, compresser un fichier (potentiellement volumineux) de manière asynchrone:

 public static async Task CompressFileAsync(ssortingng inputFile, ssortingng 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(); } } 

A partir du code client POV:

EAP: Vous configurez un gestionnaire d’événements pour un événement dont le nom se termine par “Completed”, puis appelez une méthode dont le nom se termine par “Async”. Vous pouvez parfois appeler une méthode avec le nom “Cancel” qui pourrait l’annuler.

APM: Vous appelez une méthode dont le nom commence par “Begin”, puis interrogez le résultat ou recevez un rappel, puis appelez une méthode commençant par “End”.

Pour autant que je sache, l’APM est implémenté dans la plupart des classes d’E / S BCL et WCF, principalement des opérations non annulables de niveau inférieur (comme pour annuler, vous ignorez simplement le résultat). EAP se trouve sur des classes de niveau supérieur, c’est-à-dire pour télécharger un fichier, où il y a plusieurs étapes et un comportement d’annulation significatif.

Donc, si vous devez choisir lequel mettre en œuvre (et que vous vous limitez délibérément à ces deux), je suppose que cela dépend de ce que vous faites est annulable ou non.

À partir du code client POV, vous n’avez pas toujours le choix. Il est probablement préférable d’utiliser les tâches C # 4.5 si vous le pouvez. Elles peuvent fonctionner avec n’importe lequel des mécanismes async plus anciens via des wrappers.

Une réponse complète est donnée dans l’article MSDN “Décider du moment d’implémenter le modèle asynchrone basé sur les événements” .

L’idée principale de cet article (et la réponse courte à votre question) sonne comme “Générer le modèle basé sur les événements par défaut, avec une option permettant de générer le modèle IAsyncResult”