码迷,mamicode.com
首页 > Web开发 > 详细

WebService在.NET中的应用

时间:2015-09-16 00:39:41      阅读:488      评论:0      收藏:0      [点我收藏+]

标签:

提高WebService大数据量网络传输处理的性能

直接返回DataSet对象
特点:通常组件化的处理机制,不加任何修饰及处理;
优点:代码精减、易于处理,小数据量处理较快;
缺点:大数据量的传递处理慢,消耗网络资源;
建议:当应用系统在内网、专网(局域网)的应用时,或外网(广域网)且数据量在KB级时的应用时,采用此种模式。

        public DataSet GetDataSet()
        {
            string sql = "select * from XT_TEXT";
            SqlConnection conn = new SqlConnection("Server=xxxxx;DataBase=s168593;user id=s168593;password=h0y+FeC*;");
            conn.Open();
            SqlDataAdapter dataAd = new SqlDataAdapter(sql, conn);
            DataSet DS = new DataSet("XT_TEXT");
            dataAd.Fill(DS);
            conn.Close();
            return DS;
        }

Client:

        private void BindDataSet(DataSet DS)
        {
            this.dataGridView1.DataSource = DS.Tables[0];
        }


        private void button1_Click(object sender, EventArgs e)
        {
            com.dzbsoft.www.DataSetService ds = new Test.com.dzbsoft.www.DataSetService();
            DateTime dtBegin = DateTime.Now;
            DataSet DS = ds.GetDataSet();
            this.label1.Text = string.Format("耗时:{0}", DateTime.Now - dtBegin);
            BindDataSet(DS);
        }

 

返回DataSet对象用Binary序列化后的字节数组
特点:字节数组流的处理模式;
优点:易于处理,可以中文内容起到加密作用;
缺点:大数据量的传递处理慢,较消耗网络资源;
建议:当系统需要进行较大数据交换时采用。

        public byte[] GetDataSetBytes()
        {
            DataSet DS = GetDataSet();
            BinaryFormatter ser = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            ser.Serialize(ms, DS);
            byte[] buffer = ms.ToArray();
            return buffer;
        }

Client:

        private void button2_Click(object sender, EventArgs e)
        {
            com.dzbsoft.www.DataSetService ds = new Test.com.dzbsoft.www.DataSetService();
            DateTime dtBegin = DateTime.Now;
            byte[] buffer = ds.GetDataSetBytes();
            DataSet DS = ds.GetDataSet();
            BinaryFormatter ser = new BinaryFormatter();
            DataSet dataset = ser.Deserialize(new MemoryStream(buffer)) as DataSet;
            this.label2.Text = string.Format("耗时:{0}", DateTime.Now - dtBegin + "          " + buffer.Length.ToString());
            BindDataSet(DS);
        }

 

返回DataSetSurrogate对象用Binary序列化后的字节数组
特点:微软提供的开源组件;下载地址:http://support.microsoft.com/kb/829740/zh-cn
优点:易于处理,可以中文内容起到加密作用;
缺点:大数据量的传递处理慢,较消耗网络资源;
建议:当系统需要进行较大数据交换时采用。

        public byte[] GetDataSetSurrogateBytes()
        {
            DataSet DS = GetDataSet();
            DataSetSurrogate dss = new DataSetSurrogate(DS);
            BinaryFormatter ser = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            ser.Serialize(ms, dss);
            byte[] buffer = ms.ToArray();
            return buffer;
        } 

Client:

        private void button3_Click(object sender, EventArgs e)
        {
            com.dzbsoft.www.DataSetService ds = new Test.com.dzbsoft.www.DataSetService();
            DateTime dtBegin = DateTime.Now;
            byte[] buffer = ds.GetDataSetSurrogateBytes();
            BinaryFormatter ser = new BinaryFormatter();
            DataSet DS = ds.GetDataSet();
            DataSetSurrogate dss = ser.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;
            DataSet dataset = dss.ConvertToDataSet();
            this.label3.Text = string.Format("耗时:{0}", DateTime.Now - dtBegin + "          " + buffer.Length.ToString());
            BindDataSet(DS);
        } 

 

返回DataSetSurrogate对象用Binary序列化并Zip压缩后的字节数组
特点:对字节流数组进行压缩后传递;
优点:当数据量大时,性能提高效果明显,压缩比例大;
缺点:相比第三方组件,压缩比例还有待提高;
建议:当系统需要进行大数据量网络数据传递时,建议采用此种可靠、高效、免费的方法。

        public byte[] GetDataSetSurrogateZipBytes()
        {
            DataSet DS = GetDataSet();
            DataSetSurrogate dss = new DataSetSurrogate(DS);
            BinaryFormatter ser = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            ser.Serialize(ms, dss);
            byte[] buffer = ms.ToArray();
            byte[] Zipbuffer = Compress(buffer);
            return Zipbuffer;
        }

        public byte[] Compress(byte[] data)
        {
            MemoryStream ms = new MemoryStream();
            Stream zipStream = null;
            zipStream = new GZipStream(ms, CompressionMode.Compress, true);
            zipStream.Write(data, 0, data.Length);
            zipStream.Close();
            ms.Position = 0;
            byte[] compressed_data = new byte[ms.Length];
            ms.Read(compressed_data, 0, int.Parse(ms.Length.ToString()));
            return compressed_data;
        } 

Client:

        private void button4_Click(object sender, EventArgs e)
        {
            com.dzbsoft.www.DataSetService ds = new Test.com.dzbsoft.www.DataSetService();
            DateTime dtBegin = DateTime.Now;
            byte[] zipBuffer = ds.GetDataSetSurrogateZipBytes();
            byte[] buffer = UnZipClass.Decompress(zipBuffer);
            BinaryFormatter ser = new BinaryFormatter();
            DataSet DS = ds.GetDataSet();
            DataSetSurrogate dss = ser.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;
            DataSet dataset = dss.ConvertToDataSet();
            this.label4.Text = string.Format("耗时:{0}", DateTime.Now - dtBegin + "          " + zipBuffer.Length.ToString());
            BindDataSet(DS);
        } 
    public static class UnZipClass
    {
        /// <summary>
        /// Decompresses the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        public static byte[] Decompress(byte[] data)
        {
            try
            {
                MemoryStream ms = new MemoryStream(data);
                Stream zipStream = null;
                zipStream = new GZipStream(ms, CompressionMode.Decompress);
                byte[] dc_data = null;
                dc_data = ExtractBytesFormStream(zipStream, data.Length);
                return dc_data;
            }
            catch
            {
                return null;
            }
        }

        public static byte[] ExtractBytesFormStream(Stream zipStream, int dataBlock)
        {
            try
            {
                byte[] data = null;
                int totalBytesRead = 0;
                while (true)
                {
                    Array.Resize(ref data, totalBytesRead + dataBlock + 1);
                    int bytesRead = zipStream.Read(data, totalBytesRead, dataBlock);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    totalBytesRead += bytesRead;
                }
                Array.Resize(ref data, totalBytesRead);
                return data;
            }
            catch
            {
                return null;
            }
        }
    }

测试用例:SqlServer2000数据库,数据量大小40000行,字段数10个,结果如下:

使用方法 总用时(秒) 数据大小(byte)

大小百分比(%)

直接返回DataSet 12.625 19629414 100%
返回二进制序列化后DataSet 9.712 12049645 61.38%
返回转化DataSetSurrogate的DataSet并且二进制序列化后 7.943 5138990 26.18%
返回转化DataSetSurrogate的DataSet并且二进制序列化后使用zip压缩 7.619 978033 4.98%

 

 

 

 

 

 

WebService中的异步调用

调用WebService方法有两种方式,同步调用和异步调用。同步调用是程序继续执行前等候调用的完成,而异步调用在后台继续时,程序也继续执行,不必等待方法处理完成而直接返回。

同步模式:
优点:稳定、安全、可靠;
缺点:效率低下。
异步模式:
优点:高效、充分利用资源;
缺点:事务处理较为复杂,不易于控制。

下面的Demo是通过ado.net对数据库表导入导出的操作。

Host:

    public class AsynWebService : System.Web.Services.WebService
    {
        [WebMethod(Description = "复制表数据表数据库表")]
        public string CopyDataTable(string Pub_CnnD, string DestTableName, byte[] ZipByte)
        {
            byte[] buffer = UnZipClass.Decompress(ZipByte);
            BinaryFormatter ser = new BinaryFormatter();
            DataSetSurrogate dss;
            dss = (DataSetSurrogate)ser.Deserialize(new MemoryStream(buffer));
            DataSet DS = dss.ConvertToDataSet();
            int RowNum;
            RowNum = DS.Tables[0].Rows.Count;
            bool Result = DataTableFillToDb(Pub_CnnD, DestTableName, DS.Tables[0]);
            DS.Clear();
            DS.Reset();
            GC.Collect();
            if (Result == true)
            {
                return "复制表:" + DestTableName + " 的数据到远程数据成功!记录数为:" + RowNum.ToString();
            }
            else
            {
                return "复制表:" + DestTableName + " 的数据到远程数据失败!";
            }
        }

        /// <summary>
        /// 表存在的DataTable填充 
        /// </summary>
        /// <param name="Pub_CnnD">数据库联结串</param>
        /// <param name="DestTableName">目标表名</param>
        /// <param name="SouseDataTable">源DataTable</param>
        /// <returns></returns>
        private bool DataTableFillToDb(string Pub_CnnD, string DestTableName, DataTable SouseDataTable)
        {
            try
            {
                if (SouseDataTable.Rows.Count > 0)
                {
                    SqlConnection SqlCnn = new SqlConnection(Pub_CnnD);
                    SqlCnn.Open();
                    DataTable NewTable = OrdinalTable(Pub_CnnD, SouseDataTable, SouseDataTable.TableName);
                    SqlBulkCopy Bcp = new SqlBulkCopy(SqlCnn);
                    Bcp.DestinationTableName = DestTableName;
                    Bcp.WriteToServer(NewTable);
                    Bcp.Close();
                    SqlCnn.Close();
                }
                SouseDataTable.Reset();
                SouseDataTable.Dispose();
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 调整表字段顺序
        /// </summary>
        /// <param name="SqlConnstring">数据库联结串</param>
        /// <param name="DTS">源DataTable</param>
        /// <param name="TableName">表名</param>
        /// <returns></returns>
        private DataTable OrdinalTable(string SqlConnstring, DataTable DTS, string TableName)
        {
            try
            {
                System.Data.SqlClient.SqlConnection SqldbCnn = new System.Data.SqlClient.SqlConnection(SqlConnstring);
                DataTable DTD = new DataTable();
                System.Data.SqlClient.SqlDataAdapter SqlDbDA = new System.Data.SqlClient.SqlDataAdapter("select top 1 * from " + TableName, SqldbCnn);
                SqldbCnn.Open();
                SqlDbDA.Fill(DTD);
                SqlDbDA.Dispose();
                SqldbCnn.Close();
                DTD.Clear();
                int I = 0;
                int J = 0;
                string CNS = "";
                string CND = "";
                int MaxCol = 0;
                for (I = 0; I <= DTS.Columns.Count - 1; I++)
                {
                    CNS = DTS.Columns[I].ColumnName;
                    for (J = 0; J <= DTD.Columns.Count - 1; J++)
                    {
                        CND = DTD.Columns[J].ColumnName;
                        if (CND.ToUpper() == CNS.ToUpper())
                        {
                            if (MaxCol < J)
                            {
                                MaxCol = J;
                                break;
                            }
                        }
                    }
                }
                for (J = 0; J <= MaxCol; J++)
                {
                    if (DTS.Columns.IndexOf(DTD.Columns[J].ColumnName) < 0)
                    {
                        DTS.Columns.Add(DTD.Columns[J].ColumnName.ToUpper(), DTD.Columns[J].DataType);
                    }
                }

                for (I = 0; I <= DTD.Columns.Count - 1; I++)
                {
                    CND = DTD.Columns[I].ColumnName;
                    for (J = 0; J <= DTS.Columns.Count - 1; J++)
                    {
                        CNS = DTS.Columns[J].ColumnName;
                        if (CNS.ToUpper() == CND.ToUpper())
                        {
                            DTS.Columns[J].SetOrdinal(I);
                            break;
                        }
                    }
                }
                return DTS;
            }
            catch
            {
                return DTS;
            }
        }

Client:

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }
        private string DestConnstring = "Server=60.28.25.58;DataBase=s168593;user id=s168593;password=h0y+FeC*;";
        private string SourceConnstring = "Server=.;DataBase=XZBWWW;user id=sa;password=sasa;";
        private void Form1_Load(object sender, EventArgs e)
        {
            SqlConnection Sconn = new SqlConnection(SourceConnstring);
            Sconn.Open();
            DataTable DT = new DataTable();
            DT = Sconn.GetSchema("Tables");
            this.listBox1.DisplayMember = "TABLE_NAME";
            this.listBox1.DataSource = DT;
            Sconn.Close();

        }

        private void listBox1_DoubleClick(object sender, EventArgs e)
        {
            localhost.AsynWebService Myservice = new Test.localhost.AsynWebService();
            Myservice.CopyDataTableCompleted += new Test.localhost.CopyDataTableCompletedEventHandler(CopyDataTableEventHandler);
            
            DataRowView DRV=(DataRowView)this.listBox1.Items[this.listBox1.SelectedIndex];
            DataSet DS=new DataSet();
            DS=GetDataSet(SourceConnstring,"select * from " + DRV["TABLE_NAME"].ToString());


            Myservice.CopyDataTableAsync(DestConnstring, DRV["TABLE_NAME"].ToString(), GetDataSetSurrogateZipBYtes(DS));
            this.textBox1.Text = this.textBox1.Text + "运行本模块完成!";

        }

        private void CopyDataTableEventHandler(object sender, localhost.CopyDataTableCompletedEventArgs e)
        {
            this.textBox1.Text = this.textBox1.Text + e.Result + System.Environment.NewLine;
        }

        public DataSet GetDataSet(string StrCnn, string StrSql)
        {
            DataSet DS = new DataSet();
            SqlDataAdapter DA = new SqlDataAdapter(StrSql, StrCnn);
            DA.Fill(DS);
            DA.Dispose();
            return DS;
        }

        public byte[] GetDataSetSurrogateZipBYtes(DataSet DS)
        {
            DataSetSurrogate dss = new DataSetSurrogate(DS);
            BinaryFormatter ser = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            ser.Serialize(ms, dss);
            byte[] buffer = ms.ToArray();
            byte[] Zipbuffer = Compress(buffer);
            return Zipbuffer;
        }
        private byte[] Compress(byte[] data)
        {
            MemoryStream ms = new MemoryStream();
            Stream zipStream = null;
            zipStream = new GZipStream(ms, CompressionMode.Compress, true);
            zipStream.Write(data, 0, data.Length);
            zipStream.Close();
            ms.Position = 0;
            byte[] Compressed_Data = new byte[ms.Length];
            ms.Read(Compressed_Data, 0, int.Parse(ms.Length.ToString()));
            return Compressed_Data;
        }
    }

动态调用WebService

代码文档对象模型CodeDom的使用和编程使用C#编译器

    public static class WebServiceHelper
    {
        /// <summary>
        /// 动态调用WebService
        /// </summary>
        /// <param name="url">WebService地址</param>
        /// <param name="methodname">方法名(模块名)</param>
        /// <param name="args">参数列表</param>
        /// <returns>object</returns>
        public static object InvokeWebService(string url, string methodname, object[] args)
        {
            return InvokeWebService(url, null, methodname, args);
        }
        /// <summary>
        /// 动态调用WebService
        /// </summary>
        /// <param name="url">WebService地址</param>
        /// <param name="classname">类名</param>
        /// <param name="methodname">方法名(模块名)</param>
        /// <param name="args">参数列表</param>
        /// <returns>object</returns>
        public static object InvokeWebService(string url, string classname, string methodname, object[] args)
        {
            string @namespace = "ServiceBase.WebService.DynamicWebLoad";
            if (classname == null || classname == "")
            {
                classname = GetClassName(url);
            }
            //获取服务描述语言(WSDL)
            WebClient wc = new WebClient();
            Stream stream = wc.OpenRead(url + "?WSDL");
            ServiceDescription sd = ServiceDescription.Read(stream);
            ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
            sdi.AddServiceDescription(sd, "", "");
            CodeNamespace cn = new CodeNamespace(@namespace);
            //生成客户端代理类代码
            CodeCompileUnit ccu = new CodeCompileUnit();
            ccu.Namespaces.Add(cn);
            sdi.Import(cn, ccu);
            CSharpCodeProvider csc = new CSharpCodeProvider();
            ICodeCompiler icc = csc.CreateCompiler();
            //设定编译器的参数
            CompilerParameters cplist = new CompilerParameters();
            cplist.GenerateExecutable = false;
            cplist.GenerateInMemory = true;
            cplist.ReferencedAssemblies.Add("System.dll");
            cplist.ReferencedAssemblies.Add("System.XML.dll");
            cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
            cplist.ReferencedAssemblies.Add("System.Data.dll");
            //编译代理类
            CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
            if (true == cr.Errors.HasErrors)
            {
                System.Text.StringBuilder sb = new StringBuilder();
                foreach (CompilerError ce in cr.Errors)
                {
                    sb.Append(ce.ToString());
                    sb.Append(System.Environment.NewLine);
                }
                throw new Exception(sb.ToString());
            }

            //生成代理实例,并调用方法
            System.Reflection.Assembly assembly = cr.CompiledAssembly;
            Type t = assembly.GetType(@namespace + "." + classname, true, true);
            object obj = Activator.CreateInstance(t);
            System.Reflection.MethodInfo mi = t.GetMethod(methodname);
            return mi.Invoke(obj, args);

        }

        private static string GetClassName(string url)
        {
            string[] parts = url.Split(/);
            string[] pps = parts[parts.Length - 1].Split(.);
            return pps[0];
        }

    }

Test WebService:

        [WebMethod]
        public string HelloWorld(string Temp1,string Temp2)
        {
            return "参数1:" + Temp1 + "  参数2:" + Temp2;
        } 

Client:

            string url = "http://localhost/InvokeService/Service1.asmx";
            string[] args = new string[2];
            args[0] = this.textBox1.Text;
            args[1] = this.textBox2.Text;

            object result = InvokeWebService.WebServiceHelper.InvokeWebService(url, "HelloWorld", args);
            this.textBox3.Text = result.ToString();

 

WebService在.NET中的应用

标签:

原文地址:http://www.cnblogs.com/laixiancai/p/4811787.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!