• Silverlight中异步调用WCF服务,传入回调函数


      以前学的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表达式,至此,回调函数就完成了。

    在开发中,自己可以根据需要完善方法。

     
  • 相关阅读:
    docker出现如下错误:Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    docker 常用的命令
    postman的使用大全
    plsql连接数据库出现乱码
    mybatis从mapper接口跳转到相应的xml文件的eclipse插件
    PWC6345: There is an error in invoking javac. A full JDK (not just JRE) is required
    解决java compiler level does not match the version of the installed java project facet【转载】
    使用maven时出现Failure to transfer 错误的解决方法
    QT5 网络通讯
    c/c++ 贪吃蛇控制台版
  • 原文地址:https://www.cnblogs.com/yunfeifei/p/3768448.html
Copyright © 2020-2023  润新知