WebService 应用(3) - 提高WebService的性能

一、一个简单的Webservice示例

  a. 在数据库中创建一个Database,名为WebServiceDemo,然后创建一个表student,插入相关测试数据。(我使用了4万多条数据,方便下面的比较测试)。

  b. 在VS中创建一个Web Service 应用程序,并调加一个 WebMethod:GetDataSet,该方法返回用"Select * From Student"查询得到的DataSet。

ExpandedBlockStart.gif GetDataSet
[WebMethod(Description  =   " 直接返回DataSet对象 " )]
public  DataSet GetDataSet()
{
    
string  sqlCmd  =   " Select * From Student " ;
    SqlConnection sqlConn 
=   new  SqlConnection(szConn);
    sqlConn.Open();
    SqlDataAdapter dataAdapter 
=   new  SqlDataAdapter(sqlCmd, sqlConn);
    DataSet sqlDS 
=   new  DataSet( " Demo " );
    dataAdapter.Fill(sqlDS);
    sqlConn.Close();
    
return  sqlDS;
}


二、Webservice部署到本地

  部署过程中,需要注意两个问题:

  1. 需要为数据库添加‘机器名\ASPNET’登录名并给予权限, 不然在客户端调用时会出现异常: System.Data.SqlClient.SqlException: 用户 '......\ASPNET' 登录失败。

  2. 需要为这个发布的service创建虚拟目录,不然会在这一行提示错误:

  <authentication mode="Windows"/>

 

三、 创建客户端----Webservice使用者

  新建一个winform程序,添加刚刚部署的webservice(References->Add Service Reference)。在form中添加一个DataGridView用来显示数据。下面会介绍几种方法,这里用一个 button的click事件对应处理一种情况,然后进行比较。

 

四、提高WebService的性能

  然而这种直接返回dataset的方法,在数据量比较大的时候,传递处理慢,消耗网络资源较多。下面介绍几种常用的方法,将dataset序列化/压缩后传输。

  1. Webservice方法返回DataSet对象用Binary序列化后的字节数组,然后在客户端进行反序列化。采用字节数组流的处理模式,易于处理。

ExpandedBlockStart.gif 代码
// Webservice
[WebMethod(Description  =   " 返回DataSet对象用Binary序列化后的字节数组 " )]
public   byte [] GetDataSetBytes()
{
    DataSet sqlDS 
=  GetDataSet();
    BinaryFormatter bFormatter 
=   new  BinaryFormatter();
    MemoryStream mStream 
=   new  MemoryStream();
    bFormatter.Serialize(mStream, sqlDS);
    
byte [] buffer  =  mStream.ToArray();
    
return  buffer;
}
// Client
///   <summary>
///  反序列化DataSet对象用Binary序列化后的字节数组
///   </summary>
///   <param name="sender"></param>
///   <param name="e"></param>
private   void  button2_Click( object  sender, EventArgs e)
{
//     DateTime dtBegin = DateTime.Now;

    
byte [] buffer  =  webService.GetDataSetBytes();
    BinaryFormatter bFormatter 
=   new  BinaryFormatter();
    DataSet dataSet 
=  bFormatter.Deserialize( new  MemoryStream(buffer))  as  DataSet;

//     this.label2.Text = string.Format("耗时:{0}", DateTime.Now - dtBegin + "          " + buffer.Length.ToString());
//     BindDataSet(dataSet);
}

  

  2. Webservice方法返回DataSetSurrogate对象用Binary序列化后的字节数组。这里用到微软提供的开源组件DataSetSurrogate.dll进行序列化。

ExpandedBlockStart.gif 代码
// WebService
[WebMethod(Description  =   " 返回DataSetSurrogate对象用Binary序列化后的字节数组 " )]
public   byte [] GetDataSetSurrogateBytes()
{
    DataSet sqlDS  =  GetDataSet();
    DataSetSurrogate dss  =   new  DataSetSurrogate(sqlDS);
    BinaryFormatter bFormatter  =   new  BinaryFormatter();
    MemoryStream mStream  =   new  MemoryStream();
    bFormatter.Serialize(mStream, dss);

    
byte [] buffer  =  mStream.ToArray();
    
return  buffer;
}

// Client
///   <summary>
///  反序列化DataSetSurrogate对象用Binary序列化后的字节数组(Microsoft组件处理)
///   </summary>
///   <param name="sender"></param>
///   <param name="e"></param>
private   void  button3_Click( object  sender, EventArgs e)
{
//     DateTime dtBegin = DateTime.Now;

    
byte [] buffer  =  webService.GetDataSetSurrogateBytes();
    BinaryFormatter bFormatter  =   new  BinaryFormatter();

    DataSetSurrogate dss  =  bFormatter.Deserialize( new  MemoryStream(buffer))  as  DataSetSurrogate;
    DataSet dataSet  =  dss.ConvertToDataSet();

//     this.label3.Text = string.Format("耗时:{0}", DateTime.Now - dtBegin + "          " + buffer.Length.ToString());
//     BindDataSet(dataSet);
}

  

  3. Webservice方法返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组。

ExpandedBlockStart.gif 代码
// WebService
[WebMethod(Description  =   " 返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组 " )]
public   byte [] GetDataSetSurrogateZipBytes()
{
    DataSet sqlDS  =  GetDataSet();
    DataSetSurrogate dss  =   new  DataSetSurrogate(sqlDS);
    BinaryFormatter bFormatter  =   new  BinaryFormatter();
    MemoryStream mStream  =   new  MemoryStream();
    bFormatter.Serialize(mStream, dss);

    
byte [] buffer  =  mStream.ToArray();
    
byte [] zipBuffer  =  Compress(buffer);
    
return  zipBuffer;
}
///   <summary>
///  zip 压缩
///   </summary>
///   <param name="data"> 初始字节数组 </param>
///   <returns> 压缩后的字节数组 </returns>
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
///   <summary>
///  返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组(Microsoft组件处理)
///   </summary>
///   <param name="sender"></param>
///   <param name="e"></param>
private   void  button4_Click( object  sender, EventArgs e)
{
    DateTime dtBegin  =  DateTime.Now;

    
byte [] zipBuffer  =  webService.GetDataSetSurrogateZipBytes();
    
byte [] buffer  =  Decompress(zipBuffer);
    BinaryFormatter bFormatter  =   new  BinaryFormatter();
    DataSetSurrogate dss  =  bFormatter.Deserialize( new  MemoryStream(buffer))  as  DataSetSurrogate;
    DataSet dataSet  =  dss.ConvertToDataSet();

    
this .label4.Text  =   string .Format( " 耗时:{0} " , DateTime.Now  -  dtBegin  +   "            "   +  zipBuffer.Length.ToString());

    BindDataSet(dataSet);
}
///   <summary>
///  Decompresses the specified data.
///   </summary>
///   <param name="data"> The data. </param>
///   <returns></returns>
private   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  =  EtractBytesFormStream(zipStream, data.Length);
        
return  dc_data;
    }
    
catch
    {
        
return   null ;
    }
}
private   byte [] EtractBytesFormStream(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 ;
    }
}


  下图是四种方法的测试结果:(Sql Server2005, 数据line>40000,4个字段)

 

 

 从这里可以下载我所用Demo的源代码

 

转载于:https://www.cnblogs.com/lantionzy/archive/2010/05/31/1747393.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值