Instrukcje: Asynchroniczne wywoływanie operacji za pomocą fabryki kanałów

W tym temacie opisano, jak klient może uzyskać dostęp do operacji usługi asynchronicznie podczas korzystania z opartej na aplikacji klienckiej ChannelFactory<TChannel>. (W przypadku wywoływania usługi przy użyciu System.ServiceModel.ClientBase<TChannel> obiektu można użyć modelu asynchronicznego wywoływania sterowanego zdarzeniami. Aby uzyskać więcej informacji, zobacz How to: Call Service Operations Asynchronously (Jak wywoływać operacje usługi asynchronicznie). Aby uzyskać więcej informacji na temat modelu asynchronicznego wywoływania opartego na zdarzeniach, zobacz Asynchroniczny wzorzec oparty na zdarzeniach (EAP)).

Usługa w tym temacie implementuje ICalculator interfejs. Klient może wywołać operacje na tym interfejsie asynchronicznie, co oznacza, że operacje, takie jakAdd, są podzielone na dwie metody, i EndAdd, z których pierwszy inicjuje wywołanie, BeginAdd a drugi z nich pobiera wynik po zakończeniu operacji. Przykład pokazujący sposób asynchronicznego implementowania operacji w usłudze, zobacz How to: Implement an Asynchronous Service Operation (Instrukcje: implementowanie operacji asynchronicznej usługi). Aby uzyskać szczegółowe informacje na temat operacji synchronicznych i asynchronicznych, zobacz Operacje synchroniczne i asynchroniczne.

Procedura

Aby asynchronicznie wywoływać operacje usługi WCF

  1. Uruchom narzędzie ServiceModel Metadata Tool (Svcutil.exe) z opcją/async, jak pokazano w poniższym poleceniu.

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

    Spowoduje to wygenerowanie asynchronicznej wersji klienta kontraktu usługi dla operacji.

  2. Utwórz funkcję wywołania zwrotnego, która ma być wywoływana po zakończeniu operacji asynchronicznej, jak pokazano w poniższym przykładowym kodzie.

    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. Aby uzyskać dostęp do operacji usługi asynchronicznie, utwórz klienta i wywołaj Begin[Operation] funkcję (na przykład BeginAdd) i określ funkcję wywołania zwrotnego, jak pokazano w poniższym przykładowym kodzie.

    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)
    

    Po wykonaniu funkcji wywołania zwrotnego klient wywołuje End<operation> (na przykład EndAdd) w celu pobrania wyniku.

Przykład

Usługa używana z kodem klienta używanym w poprzedniej procedurze implementuje ICalculator interfejs, jak pokazano w poniższym kodzie. Po stronie Add usługi operacje i Subtract kontraktu są wywoływane synchronicznie przez czas wykonywania programu Windows Communication Foundation (WCF), mimo że poprzednie kroki klienta są wywoływane asynchronicznie na kliencie. Operacje Multiply i Divide służą do asynchronicznego wywoływania usługi po stronie usługi, nawet jeśli klient wywołuje je synchronicznie. W tym przykładzie AsyncPattern właściwość ustawia wartość true. To ustawienie właściwości, w połączeniu z implementacją wzorca asynchronicznego programu .NET Framework, nakazuje środowisku uruchomieniowemu wywołanie operacji asynchronicznie.

[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