由于当前维护的项目的结构是:Winform + Webservice所以在数据传输过程中消耗了很多的性能因此在寻找一种简便实用的优化方法
先是用BinaryFormatter序列化数据集经过WebService传输后客户端接收到byte[]格式的数据再反序列化得到数据集这种方式在网络传输时间延迟比较长的情况下效果比较明显否则序列化和反序列化再传输二进制的时间甚至超过了直接传送DataSet所以是否采取这种二进制压缩数据集就没有多大意义了
后来找到上面第一篇台湾同胞的文章才发现在Vs的DataSet已经添加了一个RemotingFormat是采用另外一种方式压缩的(传说时期开源的DataSetSurrogate类)不过没有找到这个在什么地方下载试了一下Vs里面的查询条记录设置RemotingFormat = SerializationFormatBinary;
再序列化通过WebService传输客户端接收再反序列化确实效果大大的优于直接传送DataSet不仅网络传输中如此即使本机性能改善也非常明显
下面分别是WebService里面的方法和客户端反序列化取DataSet的方法
服务器上面取数据填充数据集转换为二进制格式
/**//// <summary>
/// Method for users data query with binaryFormatter
/// </summary>
/// <param name=err></param>
/// <returns></returns>
public byte[] BinaryUserSelect(ref string err)
{
ClearCommand();
m_commandStringBuilderAppend(SELECT * FROM t_Users ;);
DataSet dsResult = new DataSet();
byte[] bArrayResult = null;
try
{
dsResult = SqlHelperExecuteDataset(m_currentConnectionString CommandTypeText m_commandStringBuilderToString());
// 上面都是取数据的无需关心二进制压缩数据集是下面一小段
dsResultRemotingFormat = SerializationFormatBinary;
MemoryStream ms = new MemoryStream();
IFormatter bf = new BinaryFormatter();
bfSerialize(ms dsResult);
bArrayResult = msToArray();
msClose();
//
}
catch (Exception ee)
{
err = eeToString();
}
return bArrayResult;
}
通过WebService把byte[]格式的数据发送到客户端这里就是WebService自己的事情了我们无需关心
客户端接收到byte[]格式的数据对其进行反序列化得到数据集进行客户端操作
/**//// <summary>
/// Get user data with Binary format
/// </summary>
/// <returns></returns>
public DataSet GetBinaryUserData()
{
string err = ;
byte[] bUserData = svcByteArrayUserSelect(ref err);
if (err != )
{
MessageBoxShow(err);
err = ;
return null;
}
// 反序列化的过程
MemoryStream ms = new MemoryStream(bUserData);
IFormatter bf = new BinaryFormatter();
object obj = bfDeserialize(ms);
DataSet dsResult = (DataSet)obj;
//
msClose();
return dsResult;
}
同样一台机器手工生成条数据在本地使用WebService分别读取传输并在客户端显示数据集和byte[]格式的数据前者平均时间秒后者平均时间为秒之间的差别仅在传输过程的格式还有后者需要的序列化和反序列化的时间本地WebService传输的差别尚且如此通过网络传输的时间优化自然会更明显
下面微软提供的DataSetSurrogate开发包下载地址:x?scid=kb;enus;
对数据集序列化和反序列化的方法进行了一下简单的封装使其可以得到重用的效果见下面的类DatFormatter
通过GetBinaryFormatData方法可以转换数据集为二进制在服务器端使用转换数据集格式发送客户端接收得到二进制格式数据使用RetrieveDataSet方法反序列化得到数据集进行客户端操作通过这些简单的操作(序列化和反序列化将数据压缩)可以使数据集等体积庞大的对象在远程传递中的时间大大减少并且可以减少网络中断等问题对程序的影响
using System;
using SystemIO;
using SystemData;
using SystemRuntimeSerialization;
using SystemRuntimeSerializationFormattersBinary;
namespace Common
{
public class DataFormatter
{
private DataFormatter() { }
/**//// <summary>
/// Serialize the Data of dataSet to binary format
/// </summary>
/// <param name=dsOriginal></param>
/// <returns></returns>
static public byte[] GetBinaryFormatData(DataSet dsOriginal)
{
byte[] binaryDataResult = null;
MemoryStream memStream = new MemoryStream();
IFormatter brFormatter = new BinaryFormatter();
dsOriginalRemotingFormat = SerializationFormatBinary;
brFormatterSerialize(memStream dsOriginal);
binaryDataResult = memStreamToArray();
memStreamClose();
memStreamDispose();
return binaryDataResult;
}
/**//// <summary>
/// Retrieve dataSet from data of binary format
/// </summary>
/// <param name=binaryData></param>
/// <returns></returns>
static public DataSet RetrieveDataSet(byte[] binaryData)
{
DataSet dataSetResult = null;
MemoryStream memStream = new MemoryStream(binaryData);
IFormatter brFormatter = new BinaryFormatter();
object obj = brFormatterDeserialize(memStream);
dataSetResult = (DataSet)obj;
return dataSetResult;
}
}
}