以前學的ASP.NET,呼叫的都是同步方法,同步方法的好處就是,一步一步走,完成這步才會走下一步。然而,WCF使用的都是非同步方法,呼叫之後不管有沒有獲得結果就直接往下走,最可惡的是非同步函式都是Void型別,得不到返回結果,雖然有Completed的事件處理,但是還是感覺比較束縛,無法與前端互動。
這裡就跟大家分享一種傳入回撥函式的方法,把前臺的方法寫好,傳到後臺,讓非同步方法呼叫完成時執行。廢話不多說了,開始寫程式碼:
首先,要先建一個帶網站的sliverlight專案,這裡就不細說了,在網站中新增一個Silverlight-enabled Wcf Service,隨便寫一個方法,就用自動生成的Dowork方法吧,下面是程式碼:
using System; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Activation; namespace Silverlight.Web { [ServiceContract(Namespace = "")] [SilverlightFaultBehavior] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Service { [OperationContract] public string DoWork() { // Add your operation implementation here return "OK,this WCF Server is running..."; } // Add more operations here and mark them with [OperationContract] } }
方法很簡單,就是返回一個字串,下面在Sliverlight中新增服務引用,引用剛才新建的服務,然後寫一個測試方法,程式碼如下:
public void Test(Action<string> callback) { ServiceReference1.ServiceClient sc = new ServiceReference1.ServiceClient(); sc.DoWorkAsync(callback); sc.DoWorkCompleted += new EventHandler<ServiceReference1.DoWorkCompletedEventArgs>(sc_DoWorkCompleted); }
這個方法呼叫了WCF服務的方法,並繫結了Completed的事件,這裡需要注意的是,我們的WCF中的DoWork方法並沒有任何引數,這裡卻傳入了一個Action<T>委託,沒錯,這個就是回撥函式,DoWorkAsync() 系統預設有個過載方法DoWorkAsync(object userState),有個引數為object userState,所以可以對這個引數賦值,把我們的回撥函式傳進去,下面是回撥函式的呼叫:
void sc_DoWorkCompleted(object sender, ServiceReference1.DoWorkCompletedEventArgs e) { CallBackMethod<string>(e,() => {return e.Result;}); } public void CallBackMethod<T>(AsyncCompletedEventArgs e, Func<T> GetT) { if (e.UserState != null) { (e.UserState as Action<T>)(GetT()); } }
這裡是最精簡的寫法,當然可以自己擴充套件,新增錯誤處理等,使其功能變的更加強大,但這裡主要就是使用了userState引數,傳入了回撥函式,從而執行的。
(e.UserState as Action<T>)(GetT());就是這句,把userState引數引數當作一個Action<T>委託執行。
接下來看看怎麼使用吧,程式碼如下:
private void button1_Click(object sender, RoutedEventArgs e) { Test(result => { if (result != null) { result += " Haha,so eazy!"; MessageBox.Show(result); } }); }
這裡回撥函式,我們傳入lambda表示式,至此,回撥函式就完成了。
在開發中,自己可以根據需要完善方法。