2009-04-05

Web Service非同步練習

在撰寫程式時我會盡量避開多執行緒問題
前陣子因為程式需求,比較常用.Net的BackgroundWorker
這次在練習撰寫Web Server時遇到一個課題

若是今天Client端程式去呼叫Web Service
而Service卻需要較長時間運算,才能回傳結果回來
那在Client端的UI會整個hold在那
這是我們開發程式的人最不想看到的樣子
(除非使用者很有耐心的等待!
不然你可以想像到,隔著螢幕後有個人一直幹樵敲鍵盤)

在微軟出的MCTS:Distributed Application Development Training Kit這本書的Chapter 7裡有大致提到使用非同步的方式。

接下來我也只是根據練習,實做下去
首先我先定義一個Delegate

public delegate string DelegateHelloWorld(string Name);

接下來使用BeginInvoke來實作
localhost.Service locService=new WinClinetPolling.localhost.Service();
 
DelegateHelloWorld myDelegate = new DelegateHelloWorld(locService.HelloWorld);
 
 
IAsyncResult result=myDelegate.BeginInvoke(textBox1.Text,null,myDelegate);
 
 
label1.Text="程式處理中,請稍候。。。";
 
 
while(!result.IsCompleted)
 
{
 
    label1.Text+="。";
    
    Application.DoEvents();
    Thread.Sleep(1000);
 
}
 
label1.Text="完成"+myDelegate.EndInvoke(result);     


其中locServer是我建立的Web Server
提供一個帶參數Method名稱為HelloWorld
這個Method中,我執行了一段程式碼
Thread.Sleep(10000);
也就是說當我呼叫這個Method時
會延遲十秒鐘後,才會回傳值

利用Delegate的BeginInvoke方式
來進行Asynchronously

其實也可以直接使用Web Service提供的
Asnyc方式,直接呼叫HelloWorldAsync
當建立了新的Web Method後,會自動提供另一個Asnyc
原本我的Method-HelloWorld
會再提供一個Asnyc的HelloWorldAsync

proxy.HelloWorldAsync(textBox2.Text, null);
 
label2.Text = "開始處理。。。請稍候!";

之後我們在去訂閱這個Method的Completed事件

proxy.HelloWorldCompleted += new WinClinetPolling.localhost.HelloWorldCompletedEventHandler(proxy_HelloWorldCompleted);

在Completed事件中

private void proxy_HelloWorldCompleted(object sender, WinClinetPolling.localhost.HelloWorldCompletedEventArgs e)
{
 if (e.Cancelled)
 {
  label2.Text = "取消了。。。";
 }
 else if (e.Error != null)
 {
  throw e.Error;
 }
 else
 {
  label2.Text = e.Result;
 }
}

先簡單記錄下來。。。

沒有留言:

張貼留言