비동기식 통신(Asynchronous communication)

.NET 웹 서비스는 웹 메서드에 대한 동기식/비동기식 호출을 지원한다. 우리가 지금까지 작성했던 클라이언트들은 웹 메서드를 호출한 후 그 결과 값이 올 때까지 다른 작업을 할 수 없는 동기식 호출을 사용했다.
비동기식 통신은 이벤트 시스템과 유사하다고 볼 수 있다. 서버쪽에 어떤 작업을 요청해놓고, 서버가 해당 작업을 완료하면 클라이언트의 특정 메서드를 호출해준다. 이러한 비동기식 통신을 하게 되면 웹 서비스로부터 응답이 올 때까지 클라이언트가 다른 작업을 계속 진행할 수 있기 때문에 작업 효율을 높일 수 있다. 이번 절에서는 WebSvcMngCClient 클라이언트가 웹 서비스와 비동기식 통신을 하도록 수정하겠다.

웹 서비스 객체를 정적 변수로 생성

웹 서비스 객체를 Form1 클래스의 정적 변수로 선언하고 생성한다.
public class Form1 : System.Windows.Forms.Form
{
   ...
   // WebSvcMngC 어셈블리의 Class1 객체를 생성한다
   private static WebSvcMngC.Class1 obj = new WebSvcMngC.Class1();
   ...

콜백 함수 작성

웹 서비스가 HelloWorld() 웹 메서드에 대한 요청에 대해 작업을 완료하였을 때 호출할 클라이언트 콜백 함수를 작성한다. WebSvcMngCClient 프로젝트의 "웹 참조" 디렉터리에 가보면 확장자가 .cs인 웹 서비스 프록시 소스가 있다. 이 소스를 보면 BeginHelloWorld(), EndHelloWorld() 메서드가 보이는데 이것이 HelloWorld() 웹 메서드를 비동기식으로 호출할 때 클라이언트가 사용하는 메서드이다. End… 메서드를 사용하면 웹 서비스가 리턴한 결과 값을 얻을 수 있다.
// HelloWorld() 웹 메서드에 대한 CallBack 함수
public static void HelloCallBack(IAsyncResult ar)
{
   // HelloWorld() 웹 메서드의 리턴값을 받는다
   string strRet = obj.EndHelloWorld(ar);

   MessageBox.Show(strRet);
}
ByeWorld() 웹 메서드에 대한 비동기식 호출에 대한 콜백 함수도 작성한다. 여기에서도 역시 EndByeWorld() 메서드를 사용하여 웹 메서드의 리턴값을 가져올 수 있다.
// ByeWorld() 웹 메서드에 대한 CallBack 함수
public static void ByeCallBack(IAsyncResult ar)
{
   // ByeWorld() 웹 메서드의 리턴값을 받는다
   string strRet = obj.EndByeWorld(ar);

   MessageBox.Show(strRet);
}

HelloWorld() 웹 메서드 비동기식 호출

"HelloWorld" 버튼의 클릭 이벤트 핸들러를 수정한다. 먼저, HelloWorld() 웹 메서드를 비동기로 호출한 후에 서버가 부를 콜백 함수에 대한 AsyncCallback 위임형을 생성한다.
AsyncCallback cb = new AsyncCallback(HelloCallBack);
BeginHelloWorld() 메서드를 사용하여 HelloWorld() 웹 메서드에 대한 비동기 호출을 시작한다.
IAsyncResult ar = obj.BeginHelloWorld(cb, null);
비동기식으로 웹 메서드를 호출하면 결과가 돌아올 때까지 다른 작업을 할 수 있음을 확인하기 위한 코드를 넣는다. 서버로부터 결과 값이 돌아왔는지의 여부는 IAsyncResult 클래스의 IsCompleted 속성으로 확인할 수 있다.
int iCounter = 0;
do
{
   label1.Text = Convert.ToString(iCounter++);
}
while (!ar.IsCompleted);

전체 소스

수정된 BtnHello_Click() 이벤트 핸들러의 전체 소스는 아래와 같다.
private void BtnHello_Click(object sender, System.EventArgs e)
{
   // 비동기 호출 후에 불리울 콜백 함수에 대한 AsyncCallback 위임형을 생성한다
   AsyncCallback cb = new AsyncCallback(HelloCallBack);

   // 비동기 호출 시작
   IAsyncResult ar = obj.BeginHelloWorld(cb, null);

   // 결과가 돌아올 때까지 다른 작업을 한다
   int iCounter = 0;
   do
   {
      label1.Text = Convert.ToString(iCounter++);
   }
   while (!ar.IsCompleted);
}

ByeWorld() 웹 메서드 비동기식 호출

"ByeWorld" 버튼의 클릭 이벤트 핸들러도 아래와 같이 수정한다. HelloWorld 버튼의 그것과 대동소이하여 따로 설명은 하지 않겠으니 주석을 참고하기 바란다.
private void BtnBye_Click(object sender, System.EventArgs e)
{
   // 비동기 호출후에 불리울 콜백 함수에 대한 AsyncCallback 위임형을 생성한다
   AsyncCallback cb = new AsyncCallback(HelloCallBack);

   // 비동기 호출 시작
   IAsyncResult ar = obj.BeginByeWorld("dizzi", cb, null);

   // 결과가 돌아올 때까지 다른 작업을 한다
   int iCounter = 0;
   do
   {
      label1.Text = Convert.ToString(iCounter++);
   }
   while (!ar.IsCompleted);
}

실행

WebSvcMngCClient.exe를 실행하고 버튼을 눌러 웹 메서드를 호출해본다. 아래는 "HelloWorld" 버튼을 눌러 HelloWorld() 웹 메서드를 비동기적으로 호출했을 때의 결과 화면이며 웹 서비스로부터 결과 값이 넘어오기까지 다른 작업(숫자 증가)이 진행되었음을 알 수 있다.

+ Recent posts