Freigeben über


Vorgehensweise: Asynchrones Aufrufen von Vorgängen mit einer Kanalfactory

In diesem Thema wird beschrieben, wie ein Client auf einen Dienstvorgang asynchron zugreifen kann, wenn eine auf ChannelFactory basierende Clientanwendung verwendet wird. (Wenn Sie ein System.ServiceModel.ClientBase-Objekt verwenden, um einen Dienst aufzurufen, können Sie das ereignisgesteuerte asynchrone Aufrufmodell verwenden. Weitere Informationen finden Sie unter Vorgehensweise: Asynchrones Aufrufen von WCF-Dienstvorgängen. Weitere Informationen über die Verwendung des ereignisgesteuerten asynchronen Aufrufmodells finden Sie unter Multithreaded Programming with the Event-based Asynchronous Pattern.

Der in diesem Thema behandelte Dienst implementiert die ICalculator-Schnittstelle. Der Client kann die Vorgänge an dieser Schnittstelle asynchron aufrufen. Dies bedeutet, dass Vorgänge wie Add in zwei Methoden aufgeteilt werden, BeginAdd und EndAdd, wobei die erste den Aufruf einleitet und die zweite das Ergebnis abruft, wenn der Vorgang abgeschlossen ist. Ein Beispiel für das asynchrone Implementieren eines Vorgangs in einem Dienst finden Sie unter Vorgehensweise: Implementieren eines asynchronen Dienstvorgangs. Einzelheiten zu synchronen und asynchronen Vorgängen finden Sie unter Synchrone und asynchrone Vorgänge.

Vorgehensweise

So rufen Sie WCF-Dienstvorgänge asynchron auf

  1. Führen Sie das ServiceModel Metadata Utility-Tool (Svcutil.exe)-Tool mit der /async-Option wie in folgendem Befehl dargestellt aus.

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

    Dies generiert eine asynchrone Clientversion des Dienstvertrags für den Vorgang.

  2. Erstellen Sie eine Rückruffunktion, die aufgerufen wird, wenn der asynchrone Vorgang abgeschlossen ist, wie im folgenden Beispielcode dargestellt.

    Private Shared Sub AddCallback(ByVal ar As IAsyncResult)
        Dim result = (CType(ar.AsyncState, CalculatorClient)).EndAdd(ar)
        Console.WriteLine("Add Result: {0}", result)
    End Sub
    
    static void AddCallback(IAsyncResult ar)
    {
        double result = ((CalculatorClient)ar.AsyncState).EndAdd(ar);
        Console.WriteLine("Add Result: {0}", result);
    }
    
  3. Zum asynchronen Aufrufen eines Dienstvorgangs erstellen Sie den Client, rufen Sie Begin[Operation] auf (z. B. BeginAdd), und geben Sie eine Rückruffunktion an, wie in folgendem Beispielcode dargestellt.

    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)
    
    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);
    

    Wenn die Rückruffunktion ausgeführt wird, ruft der Client End<operation>``EndAdd (z. B. ) auf, um das Ergebnis abzurufen.

Beispiel

Der Dienst, der mit dem im vorhergehenden Verfahren genutzten Clientcode verwendet wird, implementiert die ICalculator-Schnittstelle, wie im folgenden Beispielcode gezeigt. Auf der Seite des Diensts werden die Add- und Subtract-Vorgänge des Vertrags synchron von der Windows Communication Foundation (WCF)-Laufzeit aufgerufen, auch wenn die vorangegangenen Schritte auf dem Client asynchron aufgerufen wurden. Die Multiply- und Divide-Vorgänge werden verwendet, um den Dienst asynchron auf der Seite des Diensts aufzurufen, auch wenn der Client sie synchron aufruft. Im folgenden Beispiel wird die AsyncPattern-Eigenschaft auf true festgelegt. Diese Eigenschaftseinstellung in Verbindung mit der Implementierung des asynchronen .NET Framework-Musters weist die Laufzeit an, den Vorgang asynchron aufzurufen.

<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
[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);
}

Siehe auch

Aufgaben

Asynchron