天天看点

WebServices返回数据的4种方法比较

以前经常在群里听到朋友们说WebServices的性能特别的慢,说的如何如何。说实话,WebServices的确比调用本地数据要慢一些,可是究竟有多慢,真的如朋友们说的那么难以忍受吗?我个人感觉,多半原因在处理的方式上。让我们亲自编写测试代码,来证明这一切吧。文章由于是我一段时间的总结篇,因此难免参杂个人主观因素,说的不对的地方,还请多多批评。以下我们主要从调用WebServices的方法的特点、应用场景、测试结果三个方面来进行下说明分析。

1. 直接返回DataSet对象

  • 特点:

    直接返回DataSet对象。

  • 应用场景:

    1.内网。2.外网且数据量在kb级别时。

2.返回DataSet对象用Binary序列化后的字节数组

  • 字节数组流的处理模式。
  • 较大数据交换。

3.返回DataSetSurrogate对象用Binary 序列化后的字节数组 

  • 使用微软提供的开源组件进行序列化,依然是字节流的处理模式。详情请参考:​​http://support.microsoft.com/kb/829740/zh-cn​​

4.返回DataSetSurrogate对象用Binary 序列化并Zip压缩后的字节数组

  • 使用微软提供的开源组件对字节流数组进行压缩后传递,依然是字节流的处理模式。详情请参考:​​http://support.microsoft.com/kb/829740/zh-cn​​
  • 外网环境需要进行大数据量网络数据传递时,建议采用此种方法。也是笔者强烈向大家推荐使用的一种方法。

WebServices的代码如下:

using System;

using System.Collections.Generic;

using System.Web;

using System.Web.Services;

using System.Data;

using Microsoft.Practices.EnterpriseLibrary.Common;

using Microsoft.Practices.EnterpriseLibrary.Data;

using System.IO;

using System.IO.Compression;

using System.Runtime.Serialization.Formatters.Binary;

namespace WebService1

{

    /// <summary>

    /// Service1 的摘要说明

    /// </summary>

    [WebService(Namespace = "​​http://tempuri.org/​​")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    [System.ComponentModel.ToolboxItem(false)]

    public class Service1 : System.Web.Services.WebService

    {

        [WebMethod(Description="直接返回DataSet对象")]

        public DataSet GetDataSet()

        {

            string sql = "select * from Customers";

            Database db = DatabaseFactory.CreateDatabase();

            DataSet ds = db.ExecuteDataSet(CommandType.Text,sql);

            return ds;

        }

        [WebMethod(Description = "返回DataSet对象用Binary序列化后的字节数组")]

        public byte[] GetBytes()

            DataSet ds = GetDataSet();

            BinaryFormatter bf = new BinaryFormatter();

            MemoryStream ms = new MemoryStream();

            bf.Serialize(ms, ds);

            byte[] buffer = ms.ToArray();

            return buffer;

        [WebMethod(Description = "返回DataSetSurrogate对象用Binary序列化后的字节数组")]

        public byte[] GetDataSetSurrogateBytes()

            DataSetSurrogate dss = new DataSetSurrogate(ds);

            bf.Serialize(ms,dss);

        [WebMethod(Description = "返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组")]

        public byte[] GetDataSetSurrogateZipBytes()

            DataSet DS = GetDataSet();

            DataSetSurrogate dss = new DataSetSurrogate(DS);

            bf.Serialize(ms, dss);

            byte[] Zipbuffer = Compress(buffer);

            return Zipbuffer;

        //压缩压缩后的字节数组

        public byte[] Compress(byte[] data)

            Stream zipStream = new GZipStream(ms, CompressionMode.Compress, true);

            zipStream.Write(data, 0, data.Length);

            zipStream.Close();

            ms.Position = 0;

            byte[] buffer = new byte[ms.Length];

            ms.Read(buffer, 0,int.Parse(ms.Length.ToString()));

    }

}

客户端调用WebServices的代码如下:

using System.Web.UI;

using System.Web.UI.WebControls;

using WebServicesClient.localhost;

using System.Diagnostics;

namespace WebServicesClient

    public partial class _Default : System.Web.UI.Page

        Service1 s = new Service1();

        protected void Page_Load(object sender, EventArgs e)

        //直接返回DataSet对象

        protected void Button1_Click(object sender, EventArgs e)

            Stopwatch sw = new Stopwatch();

            sw.Start();

            DataSet ds = s.GetDataSet();

            GridView1.DataSource = ds.Tables[0].DefaultView;

            GridView1.DataBind();

            sw.Stop();

            Label1.Text = string.Format("耗时:{0}毫秒", sw.ElapsedMilliseconds.ToString());

        //得到DataSet对象用Binary序列化后的字节数组

        protected void Button2_Click(object sender, EventArgs e)

            byte[] buffer = s.GetBytes();

            DataSet ds = bf.Deserialize(new MemoryStream(buffer)) as DataSet;

            Label2.Text = string.Format("耗时:{1}毫秒;数据大小:{0}", buffer.Length.ToString(), sw.ElapsedMilliseconds.ToString());

        //得到DataSetSurrogate对象用Binary序列化后的字节数组

        protected void Button3_Click(object sender, EventArgs e)

            byte[] buffer = s.GetDataSetSurrogateBytes();

            DataSetSurrogate dss = bf.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;

            DataSet ds = dss.ConvertToDataSet();

            Label3.Text = string.Format("耗时:{1}毫秒;数据大小:{0}", buffer.Length.ToString(), sw.ElapsedMilliseconds.ToString());

        //得到DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组

        protected void Button4_Click(object sender, EventArgs e)

            byte[] zipBuffer = s.GetDataSetSurrogateZipBytes();

            byte[] buffer = UnZip.Decompress(zipBuffer);

            Label4.Text = string.Format("耗时:{1}毫秒;数据大小:{0}",zipBuffer.Length.ToString(),sw.ElapsedMilliseconds.ToString());

测试的结果按照先后顺序如下图所示:

WebServices返回数据的4种方法比较

关于测试结果的特殊说明,由于测试环境是在本地,数据量也不是很大,测试的结果离实际情况还不是很接近,如果大家有条件的话,可以测试一下,同时希望把测试的结果提供给大家参考。

最后,为了方便大家,这里还提供了源码下载,