在撰寫程式時我會盡量避開多執行緒問題
前陣子因為程式需求,比較常用.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);
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; } }
先簡單記錄下來。。。