zoukankan      html  css  js  c++  java
  • [转]web service实现原理与异步调用

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

        简单范例

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

    [WebMethod]
       public DataSet ExecuteQuery(string SQL)
            {
                using (OracleConnection conn = new OracleConnection(connstrSQL))
                {
                    try
                    {
                        conn.Open();
                        OracleCommand cmd = new OracleCommand(sql,conn);
                        OracleDataAdapter ada = new OracleDataAdapter(cmd);
                        DataSet ds = new DataSet();
                        ada.Fill(ds);
                        return ds;
                    }
                    catch (OracleException ex)
                    {
                        throw new Exception(ex.Message);
                    }
                    finally
                    {
                        conn.Close();
                    }
            }
        客户端:

    ///说明:
    ///panel1中放置了动态加载字样的图片等
    ///  
    public partial class frmStock : Form
        {
            Service.MyService w = new Service.MyService(); //调用web service
            public frmStock()
            {
                InitializeComponent();
            }
            private void frmStock_Load(object sender, EventArgs e)
            {
                //添加异步方法执行后触发事件
                w.ExecuteQueryCompleted += new WMS.ExecuteQueryCompletedEventHandler(w_ExecuteQueryCompleted);
            }
            private void btnFind_Click(object sender, EventArgs e)
            {
                string sql = "select * from test";
                 w.ExecuteQueryAsync(sql);  //调用对应异步方法
                 ChangeStatus(true);
            }
            void w_ExecuteQueryCompleted(object sender, WMS.ExecuteQueryCompletedEventArgs e)
            {
               DataTable dt= e.Result.Tables[0];  //获得执行结果 e
               ChangeStatus(false);
               if (dt.Rows.Count <= 0)
               {
                   MessageBox.Show("没有数据", "information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                   return;
               }
               gvshow.AutoGenerateColumns = false;
               gvshow.DataSource = dt;
            }
            private void btnExit_Click(object sender, EventArgs e)
            {
                this.Close();
            }
            private void ChangeStatus(bool sign)
            {
                panel1.Visible = sign;
            }
        }
       这样,可以

        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就是生成的代理类,打开可见,其中涉及到异步方法,事件的生成。(部分代码如下)

    /// <remarks/>
        public event HelloWorldCompletedEventHandler HelloWorldCompleted;
        /// <remarks/>
        public event showInfoCompletedEventHandler showInfoCompleted;
        /// <remarks/>
        [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)]
        public string HelloWorld() {
            object[] results = this.Invoke("HelloWorld", new object[0]);
            return ((string)(results[0]));
        }
        /// <remarks/>
        public System.IAsyncResult BeginHelloWorld(System.AsyncCallback callback, object asyncState) {
            return this.BeginInvoke("HelloWorld", new object[0], callback, asyncState);
        }
        /// <remarks/>
        public string EndHelloWorld(System.IAsyncResult asyncResult) {
            object[] results = this.EndInvoke(asyncResult);
            return ((string)(results[0]));
        }
        /// <remarks/>
        public void HelloWorldAsync() {
            this.HelloWorldAsync(null);
        }
        /// <remarks/>
        public void HelloWorldAsync(object userState) {
            if ((this.HelloWorldOperationCompleted == null)) {
                this.HelloWorldOperationCompleted = new System.Threading.SendOrPostCallback(this.OnHelloWorldOperationCompleted);
            }
            this.InvokeAsync("HelloWorld", new object[0], this.HelloWorldOperationCompleted, userState);
        }
        private void OnHelloWorldOperationCompleted(object arg) {
            if ((this.HelloWorldCompleted != null)) {
                System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                this.HelloWorldCompleted(this, new HelloWorldCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
            }
        }
        /// <remarks/>
        4.通过csc命令把service.cs生成为dll文件

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

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

        设计模式的应用

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

    原作者:http://blog.csdn.net/JustLovePro/archive/2008/08/27/2836898.aspx

  • 相关阅读:
    .net log4dll的使用
    Myslq 5.7安装
    接口和抽象类有什么区别
    monkey测试
    JDK、Jmeter、Android环境变量配置
    聊天室
    tushrea知识笔记
    爬取图片
    python gui之tkinter事件处理
    ttk.Treeview
  • 原文地址:https://www.cnblogs.com/iwaitu/p/1690086.html
Copyright © 2011-2022 走看看