Partager via


Procédure : appeler des opérations de façon asynchrone à l’aide d’une fabrique de canaux

Cette rubrique décrit comment un client peut accéder de façon asynchrone à une opération de service lors de l'utilisation d'une application cliente basée sur ChannelFactory<TChannel>. (Lors de l'utilisation d'un objet System.ServiceModel.ClientBase<TChannel> pour appeler un service, vous pouvez utiliser le modèle d'appel asynchrone commandé par événement. Pour plus d’informations, consultez Guide pratique pour appeler des opérations de service de façon asynchrone. Pour plus d’informations sur le modèle d’appel asynchrone basé sur les événements, consultez Modèle asynchrone basé sur les événements (EAP).

Le service dans cette rubrique implémente l'interface ICalculator. Le client peut appeler les opérations sur cette interface de façon asynchrone, ce qui signifie que des opérations telles que Add sont divisées en deux méthodes : BeginAdd et EndAdd, la première initiant l'appel et la seconde récupérant le résultat au terme de l'opération. Pour obtenir un exemple montrant comment implémenter une opération de façon asynchrone dans un service, consultez Guide pratique pour implémenter une opération de service asynchrone. Pour plus d’informations sur les opérations synchrones et asynchrones, consultez Opérations synchrones et asynchrones.

Procédure

Pour appeler des opérations de service WCF de façon asynchrone

  1. Exécutez l’outil Service Model Metadata Tool (Svcutil.exe) avec l’option /async, comme indiqué dans la commande suivante.

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

    Cela génère une version cliente asynchrone du contrat de service pour l'opération.

  2. Créez une fonction de rappel à appeler au terme de l'opération asynchrone en vous conformant à l'exemple de code suivant.

    static void AddCallback(IAsyncResult ar)
    {
        double result = ((CalculatorClient)ar.AsyncState).EndAdd(ar);
        Console.WriteLine("Add Result: {0}", result);
    }
    
    Private Shared Sub AddCallback(ByVal ar As IAsyncResult)
        Dim result = (CType(ar.AsyncState, CalculatorClient)).EndAdd(ar)
        Console.WriteLine("Add Result: {0}", result)
    End Sub
    
  3. Pour accéder de façon asynchrone à une opération de service, créez le client, puis appelez la méthode Begin[Operation] (par exemple, BeginAdd) et spécifiez une fonction de rappel en vous conformant à l'exemple de code suivant.

    ChannelFactory<ICalculatorChannel> factory = new ChannelFactory<ICalculatorChannel>();
    ICalculatorChannel channelClient = factory.CreateChannel();
    
    // BeginAdd
    double value1 = 100.00D;
    double value2 = 15.99D;
    
    IAsyncResult arAdd = channelClient.BeginAdd(value1, value2, AddCallback, channelClient);
    Console.WriteLine("Add({0},{1})", value1, value2);
    
    Dim factory As New ChannelFactory(Of ICalculatorChannel)()
    Dim channelClient As ICalculatorChannel = factory.CreateChannel()
    
    ' BeginAdd
    Dim value1 = 100.0R
    Dim value2 = 15.99R
    
    Dim arAdd As IAsyncResult = channelClient.BeginAdd(value1, value2, AddressOf AddCallback, channelClient)
    Console.WriteLine("Add({0},{1})", value1, value2)
    

    Lors de l'exécution de la fonction de rappel, le client appelle la méthode End<operation> (par exemple, EndAdd) pour récupérer le résultat.

Exemple

Le service utilisé avec le code client utilisé dans la procédure précédente implémente l'interface ICalculator comme affiché dans le code suivant. Du côté du service, les opérations Add et Subtract du contrat sont appelées de façon synchrone par le runtime Windows Communication Foundation (WCF), même si les étapes de client précédentes sont appelées de façon asynchrone sur le client. Les opérations Multiply et Divide sont utilisées pour appeler de façon asynchrone le service du côté service, même si le client les appelle de façon synchrone. Cet exemple affecte la propriété AsyncPattern à true. Ce paramètre de propriété, en combinaison avec l’implémentation du modèle asynchrone du .NET Framework, indique au runtime d’appeler l’opération de manière asynchrone.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);

    [OperationContract]
    double Subtract(double n1, double n2);

    //Multiply involves some file I/O so we'll make it Async.
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginMultiply(double n1, double n2, AsyncCallback callback, object state);
    double EndMultiply(IAsyncResult ar);

    //Divide involves some file I/O so we'll make it Async.
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginDivide(double n1, double n2, AsyncCallback callback, object state);
    double EndDivide(IAsyncResult ar);
}
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
    <OperationContract> _
    Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double

    <OperationContract> _
    Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double

    'Multiply involves some file I/O so we'll make it Async.
    <OperationContract(AsyncPattern:=True)> _
    Function BeginMultiply(ByVal n1 As Double, ByVal n2 As Double, ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
    Function EndMultiply(ByVal ar As IAsyncResult) As Double

    'Divide involves some file I/O so we'll make it Async.
    <OperationContract(AsyncPattern:=True)> _
    Function BeginDivide(ByVal n1 As Double, ByVal n2 As Double, ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
    Function EndDivide(ByVal ar As IAsyncResult) As Double
End Interface