zoukankan      html  css  js  c++  java
  • 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.

     

        设计模式的应用

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

  • 相关阅读:
    socket
    IPv4 IPv6
    2变量与基本类型之const限定符
    15面向对象程序设计
    深度探索C++对象模型之第三章:数据语义学
    线段树(成段更新) 之 poj 3468 A Simple Problem with Integers
    USACO 之 Section 1.1 Ad Hoc Problems (已解决)
    构造字符串 之 hdu 4850 Wow! Such String!
    模拟 + 最短路 之 hdu 4849 Wow! Such City!
    简单题(需要注意一个细节) 之 hdu 4847 Wow! Such Doge!
  • 原文地址:https://www.cnblogs.com/guanjie20/p/1737834.html
Copyright © 2011-2022 走看看