共用方式為


如何使用通道工廠以異步方式呼叫作業

本主題涵蓋用戶端在使用 ChannelFactory<TChannel>型用戶端應用程式時,如何以異步方式存取服務作業。 (使用 System.ServiceModel.ClientBase<TChannel> 物件叫用服務時,您可以使用事件驅動異步呼叫模型。 如需詳細資訊,請參閱 如何:以異步方式呼叫服務作業。 如需事件型異步呼叫模型的詳細資訊,請參閱 事件架構異步模式 (EAP)

本主題中的服務會實作 ICalculator 介面。 用戶端可以異步呼叫此介面上的作業,這表示 Add 之類的作業會分割成兩種方法,BeginAddEndAdd,而前者會起始呼叫,後者會在作業完成時擷取結果。 如需示範如何在服務中異步實作作業的範例,請參閱 如何:實作異步服務作業。 如需同步和異步作的詳細資訊,請參閱 同步和異步作

程序

以異步方式呼叫 WCF 服務作業

  1. 使用 /async 選項執行 ServiceModel 元數據公用程式工具 (Svcutil.exe) 工具,如下列命令所示。

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

    這會產生作業之服務合約的異步用戶端版本。

  2. 建立回呼函式,以在異步作完成時呼叫,如下列範例程式代碼所示。

    static void AddCallback(IAsyncResult ar)
    {
        double result = ((CalculatorClient)ar.AsyncState).EndAdd(ar);
        Console.WriteLine($"Add Result: {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. 若要以異步方式存取服務作業,請建立用戶端並呼叫 Begin[Operation](例如,BeginAdd),並指定回呼函式,如下列範例程式代碼所示。

    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({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)
    

    當回呼函式執行時,用戶端會呼叫 End<operation> (例如,EndAdd),以擷取結果。

範例

與上述程式中使用的用戶端程式代碼搭配使用的服務會實作 ICalculator 介面,如下列程式代碼所示。 在服務端,合約的 AddSubtract 作業會由 Windows Communication Foundation (WCF) 執行階段同步執行,儘管先前的用戶端步驟在用戶端上是異步執行的。 MultiplyDivide 作業是用來以異步方式在服務端叫用服務,即使用戶端以同步方式叫用服務也一樣。 本範例會將 AsyncPattern 屬性設定為 true。 這個屬性設定會結合 .NET Framework 的異步模式實作,以告知執行階段以異步方式叫用作業。

[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