由於當前維護的項目的結構是: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;
}
}
}
From:http://tw.wingwit.com/Article/program/net/201311/11892.html