WCF熱門問題編程樣本(4):WCF用戶端如何非同步呼叫WCF服務?
Posted on 2010-08-01 14:28 Frank Xu Lei 閱讀(296) 評論(3) 編輯 收藏 所屬分類: SOA and EAI, WCF熱門問題編程樣本
WCF熱門問題編程樣本(4):WCF用戶端如何非同步呼叫WCF服務?
How to call WCF Service asynchronously?
【1】問題描述:
WCF用戶端如何非同步呼叫WCF服務?
How to call WCF Service asynchronously?
關於WCF如何?非同步呼叫的問題,論壇上出現了很多文章,也有很多討論的文章,包括MSDN也給出了詳細的學習資料和範例程式碼。但是很多資料過於籠統,MSDN的例子有點複雜。而我們實際項目中,要實現的需求,往往十分簡單,就是要在用戶端實現對於WCF服務作業的非同步呼叫,也就是call WCF Service asynchronously。
【2】資料收集:
這裡收集一些關於WCF非同步呼叫比較有用的參考資料和問題串連。其實關於WCF用戶端非同步呼叫WCF服務的文章很多,很多討論反而走了彎路,我們想要的就是簡單的非同步呼叫WCF服務作業的例子。這裡給出一些比較有價值的參考資料:
如何:以非同步方式調用 WCF 服務操作
How to: Call WCF Service Operations Asynchronously
ASP.NET非同步呼叫WCF
【3】非同步呼叫:
這裡需要瞭解的一個重要概念就是非同步呼叫機制,在.NET裡的非同步呼叫機制是十分重要的一個知識點。另外就是回調的概念,這裡也會使用到。.Net中的非同步呼叫實際使用的是非同步委託。非同步委託將要執行的方法提交到.Net的線程池,由線程池中的線程來執行非同步呼叫。
【4】解決辦法:
知道了.NET非同步呼叫的機制以後,我們就可以來嘗試解決這個問題。這裡本質是一樣的。但編碼的過程有點差別。
當然,最容易理解的就是我們自己寫代碼來實現非同步呼叫。
其次,Visual Studio 2008已經提供了這個支援。這個更加方便。我給出:
我們這裡給出的樣本過程呢,是基於手寫用戶端非同步呼叫代碼的。僅供參考,當然你也可以使用Visual Studio來協助完成這個過程。
【5】服務端代碼:
服務端代碼的實現十分簡單,這裡我們依然使用早期WCF的代碼,定義一個IWCFService契約,包含一個操作SayHello,這個操作實現的功能,就是接受一name參數,然後列印返回字串給用戶端,為了示範,這裡會列印出時間資訊。具體代碼如下:
//1.服務契約
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
public interface IWCFService
{
//操作契約
[OperationContract]
string SayHello(string name);
}
//2.服務類,繼承介面。實現契約
public class WCFService : IWCFService
{
//實現介面定義的方法
public string SayHello(string name)
{
Console.WriteLine("Call Operation at {0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"));
return string.Format("Hello {0}",name);
}
}
【6】用戶端代碼:
用戶端的實現大部分代碼與之前的沒有區別,為了方便,我們可以在Visual Studio產生的程式碼基礎上修改。當然也完全可以自己重寫。 這裡比較重要的一點,就是要實現非同步呼叫需要的契約以及非同步呼叫的方法。
【6.1】首先這裡要實現支援非同步呼叫的契約:
public interface IWCFService {
[System.ServiceModel.OperationContractAttribute(Action="http://www.cnblogs.com/frank_xl/IWCFService/SayHello", ReplyAction="http://www.cnblogs.com/frank_xl/IWCFService/SayHelloResponse")]
string SayHello(string name);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginSayHello(string name, AsyncCallback callback, object asyncState);
string EndSayHello(IAsyncResult result);
}
【6.2】支援非同步呼叫的用戶端代理類:
我們要在自己的WCFClient代理類裡繼承這個契約,並提供非同步作業調用的實現,具體代碼如下:
public string SayHello(string name) {
return base.Channel.SayHello(name);
}
public IAsyncResult BeginSayHello(string name, AsyncCallback callback, object asyncState)
{
return Channel.BeginSayHello(name, callback, asyncState);
}
public string EndSayHello(IAsyncResult result)
{
return Channel.EndSayHello(result);
}
【6.3】測試用戶端代碼:
用戶端代碼還有一點比較重要的地方,就是實現非同步回調方法,這裡我們在調用BeginSayHello方法的時候,不需要等待結果的返回,我們自己希望,WCF在調用完SayHello操作以後,執行一些必要的工作,比如顯示返回結果,或者對返回的資料做更深入的處理,這裡都需要使用到回呼函數。我們也可以在回調方法裡,來關閉WCF用戶端,以釋放資源。
例子代碼如下:
/// <summary>
/// This class is defined for WCF Async Call Test
/// </summary>
public class WCFClientTest
{
static public WCFServiceClient wcfServiceProxy = null;
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Yellow;
WCFClientTest client = new WCFClientTest();
wcfServiceProxy = new WCFServiceClient("WSHttpBinding_IWCFService");
string name = "Frank Xu Lei";
Console.WriteLine("Client Async Call begin at {0}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"));
//開始非同步呼叫Begin Call
wcfServiceProxy.BeginSayHello(name, client.OnCompletion, null);
Console.WriteLine("press ENTER to exit…");
Console.Read();
}
////回調方法,Callback method
void OnCompletion(IAsyncResult result)
{
string value = wcfServiceProxy.EndSayHello(result);
Console.WriteLine("Returned value is {0} at {1}",value, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"));
result.AsyncWaitHandle.Close();
wcfServiceProxy.Close();
Console.WriteLine("Asynchronous Calls is finished");
}
}
【7】運行結果:
這裡啟動宿主Host程式,然後運行WCF用戶端即可,我們可以看到宿主端和用戶端,非同步呼叫操作的時間差別,列印視窗的如下:
飛秋官網:http://www.freeeim.com/