Vorgehensweise: Asynchrones Aufrufen von Vorgängen mit einer KanalfactoryHow to: Call Operations Asynchronously Using a Channel Factory

In diesem Thema wird beschrieben, wie ein Client auf einen Dienstvorgang asynchron zugreifen kann, wenn eine auf ChannelFactory<TChannel> basierende Clientanwendung verwendet wird.This topic covers how a client can access a service operation asynchronously when using a ChannelFactory<TChannel>-based client application. (Wenn Sie ein System.ServiceModel.ClientBase<TChannel>-Objekt verwenden, um einen Dienst aufzurufen, können Sie das ereignisgesteuerte asynchrone Aufrufmodell verwenden.(When using a System.ServiceModel.ClientBase<TChannel> object to invoke a service you can use the event-driven asynchronous calling model. Weitere Informationen finden Sie unter Vorgehensweise: Aufrufen Service Vorgänge asynchron.For more information, see How to: Call Service Operations Asynchronously. Weitere Informationen über die das ereignisbasierte asynchrone Aufrufmodell finden Sie unter Multithreadprogrammierung mit dem ereignisbasierten asynchronen Muster.)For more information about the event-based asynchronous calling model, see Multithreaded Programming with the Event-based Asynchronous Pattern.)

Der in diesem Thema behandelte Dienst implementiert die ICalculator-Schnittstelle.The service in this topic implements the ICalculator interface. 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.The client can call the operations on this interface asynchronously, which means that operations like Add are split into two methods, BeginAdd and EndAdd, the former of which initiates the call and the latter of which retrieves the result when the operation completes. Ein Beispiel, das zeigt, wie einen Vorgang asynchron in einem Dienst zu implementieren, finden Sie unter Vorgehensweise: Implementieren eines asynchronen Dienstvorgangs.For an example showing how to implement an operation asynchronously in a service, see How to: Implement an Asynchronous Service Operation. Informationen zu synchronen und asynchronen Vorgängen finden Sie unter synchrone und asynchrone Vorgänge.For details about synchronous and asynchronous operations, see Synchronous and Asynchronous Operations.

ProzedurProcedure

So rufen Sie WCF-Dienstvorgänge asynchron aufTo call WCF service operations asynchronously

  1. Führen Sie die ServiceModel Metadata Utility Tool (Svcutil.exe) -tool mit der /async wie in den folgenden Befehl gezeigt.Run the ServiceModel Metadata Utility Tool (Svcutil.exe) tool with the /async option as shown in the following command.

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

    Dies generiert eine asynchrone Clientversion des Dienstvertrags für den Vorgang.This generates an asynchronous client version of the service contract for the operation.

  2. Erstellen Sie eine Rückruffunktion, die aufgerufen wird, wenn der asynchrone Vorgang abgeschlossen ist, wie im folgenden Beispielcode dargestellt.Create a callback function to be called when the asynchronous operation is complete, as shown in the following sample code.

    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. 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.To access a service operation asynchronously, create the client and call the Begin[Operation] (for example, BeginAdd) and specify a callback function, as shown in the following sample code.

    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)
    

    Wenn die Rückruffunktion ausgeführt wird, ruft der Client End<operation>``EndAdd (z. B. ) auf, um das Ergebnis abzurufen.When the callback function executes, the client calls End<operation> (for example, EndAdd) to retrieve the result.

BeispielExample

Der Dienst, der mit dem im vorhergehenden Verfahren genutzten Clientcode verwendet wird, implementiert die ICalculator-Schnittstelle, wie im folgenden Beispielcode gezeigt.The service that is used with the client code that is used in the preceding procedure implements the ICalculator interface as shown in the following code. Auf der Seite des Diensts werden die Add- und Subtract-Vorgänge des Vertrags synchron von der Windows Communication Foundation (WCF)Windows Communication Foundation (WCF)-Laufzeit aufgerufen, auch wenn die vorangegangenen Schritte auf dem Client asynchron aufgerufen wurden.On the service side, the Add and Subtract operations of the contract are invoked synchronously by the Windows Communication Foundation (WCF)Windows Communication Foundation (WCF) run time, even though the preceding client steps are invoked asynchronously on the client. 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.The Multiply and Divide operations are used to invoke the service asynchronously on the service side, even if the client invokes them synchronously. Im folgenden Beispiel wird die AsyncPattern-Eigenschaft auf true festgelegt.This example sets the AsyncPattern property to true. Diese Eigenschaftseinstellung in Verbindung mit der Implementierung des asynchronen .NET Framework.NET Framework-Musters weist die Laufzeit an, den Vorgang asynchron aufzurufen.This property setting, in combination with the implementation of the .NET Framework.NET Framework asynchronous pattern, tells the run time to invoke the operation asynchronously.

[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

Siehe auchSee Also

Dienstvertrag: Asynchrone BeispielService Contract: Asynchronous Sample