다음을 통해 공유


방법: 채널 팩터리를 사용하여 비동기적으로 작업 호출

이 주제에서는 ChannelFactory<TChannel> 기반의 클라이언트 애플리케이션을 사용할 때 클라이언트가 서비스 작업에 비동기적으로 접근할 수 있는 방법에 대해 설명합니다. (개체를 System.ServiceModel.ClientBase<TChannel> 사용하여 서비스를 호출하는 경우 이벤트 기반 비동기 호출 모델을 사용할 수 있습니다. 자세한 내용은 방법: 비동기적으로 서비스 작업 호출을 참조하세요. 이벤트 기반 비동기 호출 모델에 대한 자세한 내용은 EAP(이벤트 기반 비동기 패턴)를 참조하세요.

이 항목의 서비스는 ICalculator 인터페이스를 구현합니다. 클라이언트는 이 인터페이스의 작업을 비동기적으로 호출할 수 있습니다. 즉, 같은 Add 작업은 두 가지 메서드로 분할되며BeginAdd, EndAdd 그 중 전자는 호출을 시작하고 후자는 작업이 완료될 때 결과를 검색합니다. 서비스에서 비동기적으로 작업을 구현하는 방법을 보여 주는 예제는 방법: 비동기 서비스 작업 구현을 참조하세요. 동기 및 비동기 작업에 대한 자세한 내용은 동기 및 비동기 작업을 참조하세요.

절차

WCF 서비스 작업을 비동기적으로 호출하려면

  1. 다음 명령에서와 같이 옵션을 사용하여 /async를 실행합니다.

    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