방법: 채널 팩터리를 사용하여 비동기로 작업 호출
이 항목에서는 ChannelFactory 기반 클라이언트 응용 프로그램을 사용하여 클라이언트에서 서비스 작업에 비동기적으로 액세스하는 방법에 대해 설명합니다. 서비스를 호출하기 위해 System.ServiceModel.ClientBase 개체를 사용하는 경우 이벤트 구동 비동기 호출 모델을 사용할 수 있습니다. 자세한 내용은 방법: 비동기적으로 WCF 서비스 작업 호출을 참조하십시오. 이벤트 기반 비동기 호출 모델에 대한 자세한 내용은 Multithreaded Programming with the Event-based Asynchronous Pattern을 참조하십시오.
이 항목에서 설명하는 서비스에서는 ICalculator
인터페이스를 구현합니다. 클라이언트는 이 인터페이스의 작업을 비동기적으로 호출할 수 있는데, 이는 Add
등의 작업이 호출을 시작하는 BeginAdd
와 작업 완료 시 결과를 검색하는 EndAdd
라는 두 개의 메서드로 나뉨을 의미합니다. 서비스에서 작업을 비동기적으로 구현하는 방법에 대한 예제는 방법: 비동기 서비스 작업 구현을 참조하십시오. 동기 및 비동기 작업에 대한 자세한 내용은 동기 및 비동기 작업을 참조하십시오.
절차
WCF 서비스 작업을 비동기적으로 호출하려면
다음 명령과 같이 /async 옵션을 사용하여 ServiceModel Metadata 유틸리티 도구(Svcutil.exe) 도구를 실행합니다.
svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a
그러면 작업에 서비스 계약의 비동기 클라이언트 버전이 생성됩니다.
다음 샘플 코드와 같이 비동기 작업이 완료될 때 호출할 콜백 함수를 만듭니다.
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); }
서비스 작업에 비동기적으로 액세스하려면 다음 샘플 코드에서와 같이, 클라이언트를 만들고
Begin[Operation]
(예:BeginAdd
)을 호출하며 콜백 함수를 지정합니다.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);
콜백 함수가 실행될 때 클라이언트는 결과를 검색하기 위해
End<operation>
(예:EndAdd
)을 호출합니다.
예제
이전 절차에 사용된 클라이언트 코드와 함께 사용되는 서비스는 다음 코드에서와 같이 ICalculator
인터페이스를 구현합니다. 클라이언트가 이전 클라이언트 단계를 비동기적으로 호출하더라도 서비스 쪽에서는 계약의 Add
및 Subtract
작업을 WCF(Windows Communication Foundation) 런타임에서 동기적으로 호출합니다. 클라이언트가 Multiply
및 Divide
작업을 비동기적으로 호출하더라도 서비스 쪽에서는 이 작업을 사용하여 비동기적으로 서비스를 호출합니다. 다음 예제에서는 AsyncPattern 속성을 true로 설정합니다. 이 속성 설정을 .NET Framework 비동기 패턴 구현과 함께 사용하면 런타임에서 작업이 비동기적으로 호출됩니다.
<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);
}