Opérations synchrones et asynchronesSynchronous and Asynchronous Operations

Cette rubrique traite de l'implémentation et de l'appel des opérations de service asynchrones.This topic discusses implementing and calling asynchronous service operations.

De nombreuses applications appellent des méthodes de façon asynchrone, car elles peuvent ainsi continuer à effectuer un travail utile pendant que l'appel de méthode s'exécute.Many applications call methods asynchronously because it enables the application to continue doing useful work while the method call runs. Les services et les clients Windows Communication Foundation (WCF) peuvent participer à des appels d'opération asynchrones à deux niveaux distincts de l'application, qui procurent aux applications WCF plus de souplesse pour optimiser le débit en fonction de l'interactivité.Windows Communication Foundation (WCF) services and clients can participate in asynchronous operation calls at two distinct levels of the application, which provide WCF applications even more flexibility to maximize throughput balanced against interactivity.

Types d'opérations asynchronesTypes of Asynchronous Operations

Tous les contrats de service dans WCF, indépendamment des types de paramètres et des valeurs de retour, utilisent des attributs WCF pour spécifier un modèle d’échange de messages particulier entre le client et le service.All service contracts in WCF, no matter the parameters types and return values, use WCF attributes to specify a particular message exchange pattern between client and service. WCF route automatiquement les messages entrants et sortants vers l'opération de service appropriée ou le code client exécuté.WCF automatically routes inbound and outbound messages to the appropriate service operation or running client code.

Le client possède uniquement le contrat de service qui spécifie le modèle d’échange de messages pour une opération particulière.The client possesses only the service contract, which specifies the message exchange pattern for a particular operation. Les clients peuvent offrir au développeur un modèle de programmation de leur choix, tant que le modèle d’échange de messages sous-jacent est respecté.Clients can offer the developer any programming model they choose, so long as the underlying message exchange pattern is observed. De même, les services peuvent implémenter des opérations de quelque manière que ce soit, à condition que le modèle de message spécifié soit respecté.So, too, can services implement operations in any manner, so long as the specified message pattern is observed.

L'indépendance du contrat de service vis-à-vis de l'implémentation du service ou du client autorise les types d'exécutions asynchrones suivants dans les applications WCF :The independence of the service contract from either the service or client implementation enables the following forms of asynchronous execution in WCF applications:

  • Les clients peuvent appeler de façon asynchrone des opérations de demande/réponse à l'aide d'un échange de messages synchrone.Clients can invoke request/response operations asynchronously using a synchronous message exchange.

  • Les services peuvent implémenter de façon asynchrone une opération de demande/réponse à l’aide d’un échange de messages synchrone.Services can implement a request/response operation asynchronously using a synchronous message exchange.

  • Les échanges de messages peuvent être unidirectionnels, indépendamment de l'implémentation du client ou service.Message exchanges can be one-way, regardless of the implementation of the client or service.

Scénarios asynchrones suggérésSuggested Asynchronous Scenarios

Utilisez une approche asynchrone dans une implémentation de l'opération de service si celle-ci passe un appel bloquant, par exemple une tâche en E/S.Use an asynchronous approach in a service operation implementation if the operation service implementation makes a blocking call, such as doing I/O work. Lorsque vous êtes dans une implémentation d’opération asynchrone, essayez d’appeler des méthodes et des opérations asynchrones pour étendre le chemin d’appel asynchrone aussi loin que possible.When you are in an asynchronous operation implementation, try to call asynchronous operations and methods to extend the asynchronous call path as far as possible. Par exemple, appelez BeginOperationTwo() à partir d'un BeginOperationOne().For example, call a BeginOperationTwo() from within BeginOperationOne().

  • Utilisez une approche asynchrone dans une application cliente ou appelante dans les cas suivants :Use an asynchronous approach in a client or calling application in the following cases:

  • Si vous appelez des opérations à partir d'une application intermédiaire.If you are invoking operations from a middle-tier application. (Pour plus d’informations sur ces scénarios, consultez Applications clientes de niveau intermédiaire.)(For more information about such scenarios, see Middle-Tier Client Applications.)

  • Si vous appelez des opérations à partir d'une page ASP.NET, utiliser des pages asynchrones.If you are invoking operations within an ASP.NET page, use asynchronous pages.

  • Si vous appelez des opérations à partir de n'importe quelle application monothread, telle que Windows Forms ou Windows Presentation Foundation (WPF).If you are invoking operations from any application that is single threaded, such as Windows Forms or Windows Presentation Foundation (WPF). Lorsque vous utilisez le modèle d'appel asynchrone basé sur des événements, l'événement résultant est déclenché sur le thread d'interface utilisateur, ce qui accroît la réactivité de l'application sans exiger la gestion de plusieurs threads.When using the event-based asynchronous calling model, the result event is raised on the UI thread, adding responsiveness to the application without requiring you to handle multiple threads yourself.

  • En général, si vous avez le choix entre un appel synchrone et asynchrone, choisissez l’appel asynchrone.In general, if you have a choice between a synchronous and asynchronous call, choose the asynchronous call.

Implémentation d'une opération de service asynchroneImplementing an Asynchronous Service Operation

Les opérations asynchrones peuvent être implémentées à l'aide d'une des trois méthodes suivantes :Asynchronous operations can be implemented by using one of the three following methods:

  1. Modèle asynchrone basé sur des tâchesThe task-based asynchronous pattern

  2. Modèle asynchrone basé sur des événementsThe event-based asynchronous pattern

  3. Modèle asynchrone IAsyncResultThe IAsyncResult asynchronous pattern

Modèle asynchrone basé sur les tâches (TAP, Task-based Asynchronous Pattern)Task-Based Asynchronous Pattern

Le modèle asynchrone basé sur des tâches constitue le meilleur moyen d’implémenter des opérations asynchrones, car il est le plus facile et le plus simple.The task-based asynchronous pattern is the preferred way to implement asynchronous operations because it is the easiest and most straight forward. Pour utiliser cette méthode, implémentez simplement votre opération de service et spécifiez un type de retour Task<T>, où T est le type retourné par l'opération logique.To use this method simply implement your service operation and specify a return type of Task<T>, where T is the type returned by the logical operation. Par exemple :For example:

public class SampleService:ISampleService   
{   
   // ...  
   public async Task<string> SampleMethodTaskAsync(string msg)   
   {   
      return Task<string>.Factory.StartNew(() =>   
      {   
         return msg;   
      });   
   }  
   // ...  
}  

L’opération SampleMethodTaskAsync retourne Task<string>, car l’opération logique retourne une chaîne.The SampleMethodTaskAsync operation returns Task<string> because the logical operation returns a string. Pour plus d'informations sur le modèle asynchrone basé sur des tâches, consultez Modèle asynchrone basé sur des tâches.For more information about the task-based asynchronous pattern, see The Task-Based Asynchronous Pattern.

Avertissement

Lorsque vous utilisez le modèle asynchrone basé sur des tâches, une exception T:System.AggregateException peut être levée si une exception se produit lors de l’attente de la fin de l’opération.When using the task-based asynchronous pattern, a T:System.AggregateException may be thrown if an exception occurs while waiting on the completion of the operation. Cette exception peut se produire sur le client ou les services.This exception may occur on the client or services

Modèle asynchrone basé sur des événementsEvent-Based Asynchronous Pattern

Un service prenant en charge le modèle asynchrone basé sur des événements possédera une ou plusieurs opérations nommées MethodNameAsync.A service that supports the Event-based Asynchronous Pattern will have one or more operations named MethodNameAsync. Ces méthodes peuvent refléter des versions synchrones qui exécutent la même opération sur le thread actuel.These methods may mirror synchronous versions, which perform the same operation on the current thread. La classe peut également posséder un événement MethodNameCompleted et une méthode MethodNameAsyncCancel (ou simplement CancelAsync).The class may also have a MethodNameCompleted event and it may have a MethodNameAsyncCancel (or simply CancelAsync) method. Un client souhaitant appeler l'opération définira un gestionnaire d'événements à appeler lorsque l'opération se termine.A client wishing to call the operation will define an event handler to be called when the operation completes,

L'extrait de code suivant montre comment déclarer des opérations asynchrones à l'aide du modèle asynchrone basé sur des événements.The following code snippet illustrates how to declare asynchronous operations using the event-based asynchronous pattern.

public class AsyncExample  
{  
    // Synchronous methods.  
    public int Method1(string param);  
    public void Method2(double param);  
  
    // Asynchronous methods.  
    public void Method1Async(string param);  
    public void Method1Async(string param, object userState);  
    public event Method1CompletedEventHandler Method1Completed;  
  
    public void Method2Async(double param);  
    public void Method2Async(double param, object userState);  
    public event Method2CompletedEventHandler Method2Completed;  
  
    public void CancelAsync(object userState);  
  
    public bool IsBusy { get; }  
  
    // Class implementation not shown.  
}  

Pour plus d'informations sur le modèle asynchrone basé sur des événements, consultez Modèle asynchrone basé sur des événements.For more information about the Event-based Asynchronous Pattern, see The Event-Based Asynchronous Pattern.

Modèle asynchrone IAsyncResultIAsyncResult Asynchronous Pattern

Une opération de service peut être implémentée de façon asynchrone à l’aide de la .NET Framework modèle de <Begin> programmation asynchrone et AsyncPattern en marquant la trueméthode avec la propriété définie sur.A service operation can be implemented in an asynchronous fashion using the .NET Framework asynchronous programming pattern and marking the <Begin> method with the AsyncPattern property set to true. Dans ce cas, l’opération asynchrone est exposée dans les métadonnées sous la forme d’une opération synchrone: Elle est exposée en une seule opération avec un message de demande et un message de réponse corrélé.In this case, the asynchronous operation is exposed in metadata in the same form as a synchronous operation: It is exposed as a single operation with a request message and a correlated response message. Les modèles de programmation clients doivent ensuite choisir entre deux options.Client programming models then have a choice. Ils peuvent représenter ce modèle comme une opération synchrone ou asynchrone, tant qu'un échange de messages de réponse-demande a lieu lorsque le service est appelé.They can represent this pattern as a synchronous operation or as an asynchronous one, so long as when the service is invoked a request-response message exchange takes place.

En général, avec la nature asynchrone des systèmes, vous ne devez pas exploiter de dépendance sur les threads.In general, with the asynchronous nature of the systems, you should not take a dependency on the threads. La méthode la plus fiable pour transmettre des données à différentes étapes du traitement de la distribution des opérations consiste à utiliser les extensions.The most reliable way of passing data to various stages of operation dispatch processing is to use extensions.

Pour voir un exemple, consultez Comment : Implémentez une opérationde service asynchrone.For an example, see How to: Implement an Asynchronous Service Operation.

Pour définir une opération de contrat X exécutée de façon asynchrone quelle que soit la manière dont elle est appelée dans l'application cliente :To define a contract operation X that is executed asynchronously regardless of how it is called in the client application:

  • Définissez deux méthodes à l’aide du modèle BeginOperation et EndOperation.Define two methods using the pattern BeginOperation and EndOperation.

  • La méthode BeginOperation inclut les paramètres in et ref pour l'opération et retourne un type IAsyncResult.The BeginOperation method includes in and ref parameters for the operation and returns an IAsyncResult type.

  • La méthode EndOperation inclut un paramètre IAsyncResult ainsi que les paramètres out et ref et elle retourne le type de retour des opérations.The EndOperation method includes an IAsyncResult parameter as well as the out and ref parameters and returns the operations return type.

Par exemple, reportez-vous à la méthode suivante :For example, see the following method.

int DoWork(string data, ref string inout, out string outonly)  
Function DoWork(ByVal data As String, ByRef inout As String, _out outonly As out) As Integer  

Voici les deux méthodes pour créer une opération asynchrone :To create an asynchronous operation, the two methods would be:

[OperationContract(AsyncPattern=true)]
IAsyncResult BeginDoWork(string data,
                         ref string inout,
                         AsyncCallback callback,
                         object state);
int EndDoWork(ref string inout, out string outonly, IAsyncResult result);  
<OperationContract(AsyncPattern := True)>
Function BeginDoWork(ByVal data As String, _
                     ByRef inout As String, _
                     ByVal callback As AsyncCallback, _
                     ByVal state As Object) As IAsyncResult
Function EndDoWork(ByRef inout As String, ByRef outonly As String, ByVal result As IAsyncResult) As Integer  

Notes

L'attribut OperationContractAttribute est appliqué uniquement à la méthode BeginDoWork.The OperationContractAttribute attribute is applied only to the BeginDoWork method. Le contrat obtenu a une opération WSDL nommée DoWork.The resulting contract has one WSDL operation named DoWork.

Appels asynchrones côté clientClient-Side Asynchronous Invocations

Une application cliente WCF peut utiliser un des modèles d'appel asynchrone décrits précédemmentA WCF client application can use any of three asynchronous calling models described previously

Lors de l'utilisation du modèle basé sur des tâches, appelez simplement l'opération en utilisant le mot clé await comme indiqué dans l'extrait de code suivant.When using the task-based model, simply call the operation using the await keyword as shown in the following code snippet.

await simpleServiceClient.SampleMethodTaskAsync("hello, world");  

L’utilisation du modèle asynchrone basé sur des événements ne nécessite que l’ajout d’un gestionnaire d’événements pour recevoir une notification de la réponse, et l’événement résultant est déclenché automatiquement sur le thread d’interface utilisateur.Using the event-based asynchronous pattern only requires adding an event handler to receive a notification of the response -- and the resulting event is raised on the user interface thread automatically. Pour utiliser cette approche, spécifiez les options de commande /async et /tcv:Version35 avec l’outil Service Model Metadata Tool (Svcutil.exe), comme illustré dans l'exemple suivant.To use this approach, specify both the /async and /tcv:Version35 command options with the ServiceModel Metadata Utility Tool (Svcutil.exe), as in the following example.

svcutil http://localhost:8000/servicemodelsamples/service/mex /async /tcv:Version35  

Au terme de cette opération, l'outil Svcutil.exe génère une classe cliente WCF avec l'infrastructure d'événement qui permet à l'application appelante d'implémenter et d'affecter un gestionnaire d'événements de recevoir la réponse et prendre la mesure appropriée.When this is done, Svcutil.exe generates a WCF client class with the event infrastructure that enables the calling application to implement and assign an event handler to receive the response and take the appropriate action. Pour un exemple complet, consultez Guide pratique : Appeler des opérations de servicede façon asynchrone.For a complete example, see How to: Call Service Operations Asynchronously.

Cependant, le modèle asynchrone basé sur les événements n'est disponible que dans le .NET Framework version 3.5.NET Framework version 3.5.The event-based asynchronous model, however, is only available in .NET Framework version 3.5.NET Framework version 3.5. De plus, il n'est pas pris en charge dans le .NET Framework 3.5.NET Framework 3.5 lorsqu'un canal client WCF est créé à l'aide d'un System.ServiceModel.ChannelFactory<TChannel>.In addition, it is not supported even in .NET Framework 3.5.NET Framework 3.5 when a WCF client channel is created by using a System.ServiceModel.ChannelFactory<TChannel>. Avec les objets de canal client WCF, vous devez utiliser des objets System.IAsyncResult pour appeler vos opérations de manière asynchrone.With WCF client channel objects, you must use System.IAsyncResult objects to invoke your operations asynchronously. Pour utiliser cette approche, spécifiez l'option de commande async avec l’outil ServiceModel Metadata Utility Tool (Svcutil.exe), comme illustré dans l'exemple suivant.To use this approach, specify the /async command option with the ServiceModel Metadata Utility Tool (Svcutil.exe), as in the following example.

svcutil http://localhost:8000/servicemodelsamples/service/mex /async   

Vous générez ainsi un contrat de service dans lequel chaque opération est modelée comme une méthode <Begin> et où la propriété AsyncPattern a la valeur true et une méthode correspondante <End>.This generates a service contract in which each operation is modeled as a <Begin> method with the AsyncPattern property set to true and a corresponding <End> method. Pour obtenir un exemple complet d' ChannelFactory<TChannel>utilisation d' un, consultez Procédure: Appeler des opérations de façon asynchrone à l'aide d’une fabrique de canaux.For a complete example using a ChannelFactory<TChannel>, see How to: Call Operations Asynchronously Using a Channel Factory.

Dans l'un ou l'autre cas, les applications peuvent appeler une opération de façon asynchrone même si le service est implémenté de façon synchrone, de la même façon qu'une application peut utiliser le même modèle pour appeler une méthode synchrone locale de façon asynchrone.In either case, applications can invoke an operation asynchronously even if the service is implemented synchronously, in the same way that an application can use the same pattern to invoke asynchronously a local synchronous method. La façon dont l’opération est implémentée n’a pas d’importance pour le client; Lorsque le message de réponse arrive, son contenu est distribué à la méthode de > <Endasynchrone du client et le client récupère les informations.How the operation is implemented is not significant to the client; when the response message arrives, its content is dispatched to the client's asynchronous <End> method and the client retrieves the information.

Modèles d’échange de messages unidirectionnelsOne-Way Message Exchange Patterns

Vous pouvez également créer un modèle d'échange de messages asynchrone dans lequel les opérations unidirectionnelles (les opérations pour lesquelles OperationContractAttribute.IsOneWay a la valeur true n'ont aucune réponse corrélée) peuvent être envoyées dans chaque direction par le client ou le service, indépendamment du côté opposé.You can also create an asynchronous message exchange pattern in which one-way operations (operations for which the OperationContractAttribute.IsOneWay is true have no correlated response) can be sent in either direction by the client or service independently of the other side. (Cette méthode utilise le modèle d’échange de messages duplex avec des messages unidirectionnels.) Ainsi, le contrat de service spécifie un échange de messages unidirectionnels que chaque côté peut mettre en œuvre comme des appels ou implémentations asynchrones, ou synchrones, selon le cas.(This uses the duplex message exchange pattern with one-way messages.) In this case, the service contract specifies a one-way message exchange that either side can implement as asynchronous calls or implementations, or not, as appropriate. En général, lorsque le contrat est un échange de messages unidirectionnels, les implémentations sont en grande partie asynchrones car, après l'envoi d'un message, l'application n'attend pas de réponse et peut continuer à effectuer d'autres tâches.Generally, when the contract is an exchange of one-way messages, the implementations can largely be asynchronous because once a message is sent the application does not wait for a reply and can continue doing other work.

Contrats de message et clients asynchrones basés sur les événementsEvent-based Asynchronous Clients and Message Contracts

Les règles de conception pour le modèle asynchrone basé sur les événements stipulent que si plusieurs valeurs sont retournées, une valeur est retournée comme la propriété Result et les autres sont retournées comme les propriétés sur l'objet EventArgs.The design guidelines for the event-based asynchronous model state that if more than one value is returned, one value is returned as the Result property and the others are returned as properties on the EventArgs object. Il en découle que si un client importe des métadonnées à l'aide des options de commande asynchrone basées sur les événements et que l'opération retourne plusieurs valeurs, l'objet EventArgs par défaut retourne une valeur comme la propriété Result et le reste sont des propriétés de l'objet EventArgs.One result of this is that if a client imports metadata using the event-based asynchronous command options and the operation returns more than one value, the default EventArgs object returns one value as the Result property and the remainder are properties of the EventArgs object.

Pour recevoir l'objet message comme propriété Result et pour que les valeurs retournées sur cet objet soient des propriétés, utilisez l'option de commande /messageContract.If you want to receive the message object as the Result property and have the returned values as properties on that object, use the /messageContract command option. Cette opération génère une signature qui retourne le message de réponse comme la propriété Result sur l'objet EventArgs.This generates a signature that returns the response message as the Result property on the EventArgs object. Toutes les valeurs de retour internes sont ensuite des propriétés de l'objet de message de réponse.All internal return values are then properties of the response message object.

Voir aussiSee also