Silverlight中非同步呼叫WCF服務,傳入回撥函式

雲霏霏發表於2014-06-04

  以前學的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表示式,至此,回撥函式就完成了。

在開發中,自己可以根據需要完善方法。

 

相關文章