Asynchronous

Cet exemple montre comment un client peut accéder à une opération de service de façon asynchrone et comment un service peut implémenter ses opérations de façon asynchrone. Il est basé sur Getting Started, exemple qui implémente un service de calculatrice. L'utilisation de l'appel synchrone ou asynchrone est une décision locale et n'affecte pas les messages envoyés sur le câble. Même si le service implémente des opérations synchrones, le client peut accéder aux opérations de service de façon asynchrone. Même si le client appelle le service de façon synchrone, le service peut implémenter des opérations de façon asynchrone.

ms751505.note(fr-fr,VS.100).gifRemarque :
La procédure d'installation ainsi que les instructions de génération correspondant à cet exemple figurent en fin de rubrique.

Dans cet exemple, le client est une application console (.exe) et le service est auto-hébergé dans une application console (.exe).

Le service implémente l'interface ICalculator. Le client peut appeler les opérations sur cette interface de façon asynchrone, cela signifiant que les opérations telles que Add dispose maintenant de BeginAdd et EndAdd.

ms751505.note(fr-fr,VS.100).gifRemarque :
Consultez la documentation .NET Framework pour plus d'informations sur le modèle asynchrone.

Le client a généré du code qui prend en charge ces opérations asynchrones. Le client a été créé en exécutant l'outil Outil Service Model Metadata Tool (Svcutil.exe) avec l'option de commande /a (async), comme suit :

svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35

La version client asynchrone du contrat de service pour l'opération Add est similaire au code suivant.

[System.ServiceModel.ServiceContractAttribute(Namespace=
                   "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [System.ServiceModel.OperationContractAttribute(
       AsyncPattern=true)]
    System.IAsyncResult BeginAdd(double n1, double n2, 
                   System.AsyncCallback callback, object asyncState);
    double EndAdd(System.IAsyncResult result);
    
    ...
}

Lorsque l'option /tcv:Version35 est spécifiée avec l'option /async, le type de client généré implémente le modèle asynchrone basé sur les événements pour appeler le service. Pour plus d'informations, consultez Vue d'ensemble du modèle asynchrone basé sur des événements (page pouvant être en anglais). Pour accéder à une opération de service de façon asynchrone, l'application ajoute un gestionnaire d'événements à l'événement [Operation]Completed sur le client, puis appelle la méthode [Operation]Async (par exemple, AddAsync), tel qu'indiqué dans l'exemple de code suivant.

// Create a client.
CalculatorClient client = new CalculatorClient();

// BeginAdd.
double value1 = 100.00D;
double value2 = 15.99D;

client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);

Dans l'exemple, le client démarre deux opérations de façon asynchrone : Add et Subtract.

Lors de l'exécution de la fonction de rappel, le client accède à la propriété Result sur le paramètre d'entrée [Operation]CompletedEventArgs pour récupérer le résultat.

static void AddCallback(object sender, AddCompletedEventArgs e)
{
 Console.WriteLine("Add Result: {0}", e.Result);
}

Le comportement asynchrone est local au client et n'a aucune incidence sur la façon dont les messages sont envoyés par le client ou traités par le service. La raison la plus courante d'utiliser ce modèle dans une application d'interface utilisateur (UI) est de garder le thread UI libre pour la mise à jour de l'écran. Ce modèle est également applicable lorsqu'un service agit comme un client et que vous souhaitez libérer le thread de traitement de message des appels à d'autres services. La section suivante montre comment rendre des opérations de service asynchrones.

Le service implémente l'interface ICalculator, tel qu'indiqué dans le code suivant.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    
    [OperationContract]
    double Subtract(double n1, double n2);
    
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginMultiply(double n1, double n2,
        AsyncCallback callback, object state);
    double EndMultiply(IAsyncResult ar);

    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginDivide(double n1, double n2, 
        AsyncCallback callback, object state);
    double EndDivide(IAsyncResult ar); 
}

Les deux premières opérations du contrat sont appelées de façon synchrone par l'exécution Windows Communication Foundation (WCF). Les deux dernières paires d'opérations permettent d'appeler le service de façon asynchrone. Cet exemple affecte true à la propriété AsyncPattern. Ce paramètre de propriété, ainsi que l'implémentation du modèle asynchrone du .NET Framework indiquent à l'exécution d'appeler l'opération de façon asynchrone.

La raison la plus courante d'utiliser ce modèle dans une implémentation de service est de libérer les threads de traitement de message lors d'opérations d'entrée et de sortie fastidieuses telles que l'accès au disque, l'accès à une base de données ou l'appel d'un autre service. Cet exemple montre comment encapsuler les opérations d'entrée et de sortie de fichier avec une implémentation de IAsyncResult. Vous pouvez réutiliser la classe de base pour l'implémentation de la classe MathAsyncResult pour écrire vos propres implémentations de IAsyncResult.

ms751505.note(fr-fr,VS.100).gifRemarque :
Cet exemple utilise PerCall et Multiple pour empêcher le comportement de classement qui est doté d'une liaison de session. wsHttpBinding utilise une session par défaut pour établir le contexte de sécurité. Cela n'affecte pas la nature asynchrone du traitement de message sur le client ou le service, mais accentue le délai des réponses et permet au client d'examiner des rappels simultanés plutôt que de série.

Lorsque vous exécutez l'exemple, les demandes et réponses de l'opération s'affichent dans la fenêtre de console du client. Les demandes Add et Subtract ne se bloquent pas car elles sont appelées de façon asynchrone. Puis, les opérations Multiply et Divide se bloquent et leurs résultats s'affichent au moment où les demandes sortent. Enfin, les résultats des opérations Add et Subtract s'affichent lorsque ces résultats reviennent au niveau du client. sleep est utilisé dans l'implémentation du service de Add et Subtract pour afficher les rappels asynchrones sur le client.

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Add Result: 115.99
Subtract Result: 68.46

Les ID de thread sont utilisés sur le service pour montrer que les appels synchrones, tels que Add et Subtract, sont gérés sur un thread unique. Les appels asynchrones, tels que Multiply et Divide, impliquent plusieurs threads. La sortie du service se présente comme suit.

Received Add Synchronously on ThreadID 11:  Sleeping for 3 seconds
Asynchronous call: BeginMultiply on ThreadID 12
Received Subtract Synchronously on ThreadID 12:  Sleeping for 3 seconds
IO thread for * operation on ThreadID 13
EndMultiply called on ThreadID 14
Asynchronous call: BeginDivide on ThreadID 14
IO thread for / operation on ThreadID 13
EndDivide called on ThreadID 14
Returning Add Result on ThreadID 11
Returning Subtract Result on ThreadID 12

Le modèle asynchrone du .NET Framework peut être utilisé sur le client, le service, ou les deux. Comme le montre cet exemple, les deux côtés sont indépendants.

Pour configurer, générer et exécuter l'exemple

  1. Assurez-vous d'avoir effectué la procédure indiquée dans la section Procédure d'installation unique pour les exemples Windows Communication Foundation.

  2. Pour générer l'édition C# ou Visual Basic .NET de la solution, suivez les instructions indiquées dans Génération des exemples Windows Communication Foundation.

  3. Pour exécuter l'exemple dans une configuration à un ou plusieurs ordinateurs, conformez-vous aux instructions figurant dans la rubrique Running the Windows Communication Foundation Samples.

ms751505.Important(fr-fr,VS.100).gif Remarque :
Les exemples peuvent déjà être installés sur votre ordinateur. Recherchez le répertoire (par défaut) suivant avant de continuer.

<LecteurInstall>:\WF_WCF_Samples

Si ce répertoire n'existe pas, rendez-vous sur la page (éventuellement en anglais) des exemples Windows Communication Foundation (WCF) et Windows Workflow Foundation (WF) pour .NET Framework 4 pour télécharger tous les exemples Windows Communication Foundation (WCF) et WF. Cet exemple se trouve dans le répertoire suivant.

<LecteurInstall>:\WF_WCF_Samples\WCF\Basic\Contract\Service\Asynchronous