web service实现原理与异步调用

net2.0环境下,Web service中的每个方法,在Client端添加引用后生成的代理类中都会产生相应的异步方法和结束事件。我们可以利用这个异步方法和事件,轻松实现异 步调用web service.

    简单范例

    假设在web service中定义了一个数据查询的方法:


  1. [WebMethod]
  2.    public DataSet ExecuteQuery(string SQL)
  3.         {
  4.             using (OracleConnection conn = new OracleConnection(connstrSQL))
  5.             {
  6.                 try
  7.                 {
  8.                     conn.Open();

  9.                     OracleCommand cmd = new OracleCommand(sql,conn);

  10.                     OracleDataAdapter ada = new OracleDataAdapter(cmd);
  11.                     DataSet ds = new DataSet();
  12.                     ada.Fill(ds);

  13.                     return ds;
  14.                 }
  15.                 catch (OracleException ex)
  16.                 {
  17.                     throw new Exception(ex.Message);
  18.                 }
  19.                 finally
  20.                 {
  21.                     conn.Close();
  22.                 }

  23.         }

    客户端:


  1. ///说明:
  2. ///panel1中放置了动态加载字样的图 片等
  3. ///   
  4.  public partial class frmStock : Form
  5.     {
  6.         Service.MyService w = new Service.MyService(); //调用web service

  7.         public frmStock()
  8.         {
  9.             InitializeComponent();
  10.         }

  11.         private void frmStock_Load(object sender, EventArgs e)
  12.         {
  13.             //添加异步方法执行后触发事件
  14.             w.ExecuteQueryCompleted += new WMS.ExecuteQueryCompletedEventHandler(w_ExecuteQueryCompleted);

  15.         }

  16.         private void btnFind_Click(object sender, EventArgs e)
  17.         {
  18.             string sql = "select * from test";

  19.              w.ExecuteQueryAsync(sql);  //调用对应异步方法

  20.              ChangeStatus(true);

  21.         }

  22.         void w_ExecuteQueryCompleted(object sender, WMS.ExecuteQueryCompletedEventArgs e)
  23.         {
net2.0环境下,Web service中的每个方法,在Client端添加引用后生成的代理类中都会产生相应的异步方法和结束事件。我们可以利用这个异步方法和事件,轻松实现异 步调用web service.

    简单范例

    假设在web service中定义了一个数据查询的方法:


  1. [WebMethod]
  2.    public DataSet ExecuteQuery(string SQL)
  3.         {
  4.             using (OracleConnection conn = new OracleConnection(connstrSQL))
  5.             {
  6.                 try
  7.                 {
  8.                     conn.Open();

  9.                     OracleCommand cmd = new OracleCommand(sql,conn);

  10.                     OracleDataAdapter ada = new OracleDataAdapter(cmd);
  11.                     DataSet ds = new DataSet();
  12.                     ada.Fill(ds);

  13.                     return ds;
  14.                 }
  15.                 catch (OracleException ex)
  16.                 {
  17.                     throw new Exception(ex.Message);
  18.                 }
  19.                 finally
  20.                 {
  21.                     conn.Close();
  22.                 }

  23.         }

    客户端:


  1. ///说明:
  2. ///panel1中放置了动态加载字样的图 片等
  3. ///   
  4.  public partial class frmStock : Form
  5.     {
  6.         Service.MyService w = new Service.MyService(); //调用web service

  7.         public frmStock()
  8.         {
  9.             InitializeComponent();
  10.         }

  11.         private void frmStock_Load(object sender, EventArgs e)
  12.         {
  13.             //添加异步方法执行后触发事件
  14.             w.ExecuteQueryCompleted += new WMS.ExecuteQueryCompletedEventHandler(w_ExecuteQueryCompleted);

  15.         }

  16.         private void btnFind_Click(object sender, EventArgs e)
  17.         {
  18.             string sql = "select * from test";

  19.              w.ExecuteQueryAsync(sql);  //调用对应异步方法

  20.              ChangeStatus(true);

  21.         }

  22.         void w_ExecuteQueryCompleted(object sender, WMS.ExecuteQueryCompletedEventArgs e)
  23.         {
  24. DataTable dt= e.Result.Tables[0];  //获得执行结果 e
  25.      ChangeStatus(false);
  26.            if (dt.Rows.Count <= 0)
  27.            {
  28.                MessageBox.Show("没有数据""information", MessageBoxButtons.OK, MessageBoxIcon.Information);
  29.                return;
  30.            }
  31.            gvshow.AutoGenerateColumns = false;
  32.            gvshow.DataSource = dt;
  33.         }
  34.         private void btnExit_Click(object sender, EventArgs e)
  35.         {
  36.             this.Close();
  37.         }
  38.         private void ChangeStatus(bool sign)
  39.         {
  40.             panel1.Visible = sign;
  41.             
  42.         }
  43.     }
  44.    这样,可以

        1.避免了假死现象

        2.可以提供友好的用户体验

        

        实现原理

        web service 发布后,客户端添加引用,之后vs实际上在此时已经在后台生成本地代理类。之后看起来像是对web service的操作,实际上是对本地代理类的操作。代理类中处理网路访问逻辑,客户端的使用就象操作本地类一样简单便捷。

        客户端发出web service请求后,请求到达代理类,代理类处理请求从服务端获得SOAP数据包,而后进行数据处理后转发客户端。此中间涉及到的关于 SOAP,WSDL等定义,简单的可以理解为:SOAP中定义了传输数据类型的格式和规则,而WSDL则以XML的形式定义了web service的消息和有关操作,通过http传输协议进行数据传输...

        那么代理类中到底如何定义的呢?

        我们可以通过自定义代理类的方式来分析代理类的详细信息。

        1.首先创建web service:Service.asmx

        2.IIS中建立虚拟目录并发布

        3.通过WSDL.exe工具生成代理类。

        打开SDK命令提示窗口,如下作业:

    d:\Program Files\Microsoft Visual Studio 8\SDK\v2.0>wsdl http://localhost/Serve/Service.asmx?wsdl
    Microsoft (R) Web Services Description Language Utility
    [Microsoft (R) .NET Framework, Version 2.0.50727.42]
    Copyright (C) Microsoft Corporation. All rights reserved.
    Writing file 'd:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Service.cs'.

        其中service.cs就是生成的代理类,打开可见,其中涉及到异步方法,事件的生成。(部分代码 如下)

     


    1.  /// <remarks/>
    2.     public event HelloWorldCompletedEventHandler HelloWorldCompleted;
    3.     
    4.     /// <remarks/>
    5.     public event showInfoCompletedEventHandler showInfoCompleted;
    6.     
    7.     /// <remarks/>
    8.     [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    9.     public string HelloWorld() {
    10.         object[] results = this.Invoke("HelloWorld"new object[0]);
    11.         return ((string)(results[0]));
    12.     }
    13.     
    14.     /// <remarks/>
    15.     public System.IAsyncResult BeginHelloWorld(System.AsyncCallback callback, object asyncState) {
    16.         return this.BeginInvoke("HelloWorld"new object[0], callback, asyncState);
    17.     }
    18.     
    19.     /// <remarks/>
    20.     public  string EndHelloWorld(System.IAsyncResult asyncResult)
    21. {
    22.        object[] results = this.EndInvoke(asyncResult);
    23.         return ((string)(results[0]));
    24.     }
    25.     
    26.     /// <remarks/>
    27.     public void HelloWorldAsync() {
    28.         this.HelloWorldAsync(null);
    29.     }
    30.     
    31.     /// <remarks/>
    32.     public void HelloWorldAsync(object userState) {
    33.         if ((this.HelloWorldOperationCompleted == null)) {
    34.             this.HelloWorldOperationCompleted = new System.Threading.SendOrPostCallback(this.OnHelloWorldOperationCompleted);
    35.         }
    36.         this.InvokeAsync("HelloWorld"new object[0], this.HelloWorldOperationCompleted, userState);
    37.     }
    38.     
    39.     private void OnHelloWorldOperationCompleted(object arg) {
    40.         if ((this.HelloWorldCompleted != null)) {
    41.             System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
    42.             this.HelloWorldCompleted(thisnew HelloWorldCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
    43.         }
    44.     }
    45.     
    46.     /// <remarks/>

    4.通过csc命令把service.cs生成为dll文件

    5.在专案中添加对此dll的引用

    6.这样对此dll的应用实际上就是通过这个代理类访问我们发布的web service.

 

    设计模式的应用

    此种方式的实现,在设计模式中就是有名的“代理模式”的实现方式。

原文地址:https://www.cnblogs.com/guanjie20/p/1737834.html