您的位置:首页 > 大数据

WEB Service 下实现大数据量的传输

2006-07-08 13:29 363 查看
WEB Service 下实现大数据量的传输
Vs2005里面的,查询12000条记录,设置RemotingFormat = SerializationFormat.Binary;
再序列化,通过WebService传输,客户端接收,再反序列化,确实效果大大的优于直接传送DataSet,不仅网络传输中如此,即使本机,性能改善也非常明显.

下面分别是WebService里面的方法和客户端反序列化取DataSet的方法.
1. 服务器上面取数据,填充数据集,转换为二进制格式.




/**//// <summary>


/// Method for users data query with binaryFormatter


/// </summary>


/// <param name="err"></param>


/// <returns></returns>


public byte[] BinaryUserSelect(ref string err)






{


ClearCommand();


m_commandStringBuilder.Append("SELECT * FROM t_Users ;");


DataSet dsResult = new DataSet();


byte[] bArrayResult = null;


try






{


dsResult = SqlHelper.ExecuteDataset(m_currentConnectionString, CommandType.Text, m_commandStringBuilder.ToString());


// 上面都是取数据的,无需关心.二进制压缩数据集是下面一小段


dsResult.RemotingFormat = SerializationFormat.Binary;


MemoryStream ms = new MemoryStream();


IFormatter bf = new BinaryFormatter();


bf.Serialize(ms, dsResult);


bArrayResult = ms.ToArray();


ms.Close();


//


}


catch (Exception ee)






{


err = ee.ToString();


}


return bArrayResult;


}

2. 通过WebService把byte[]格式的数据发送到客户端,这里就是WebService自己的事情了,我们无需关心

3.客户端接收到byte[]格式的数据,对其进行反序列化,得到数据集,进行客户端操作.




/**//// <summary>


/// Get user data with Binary format


/// </summary>


/// <returns></returns>


public DataSet GetBinaryUserData()






{


string err = "";


byte[] bUserData = svc.ByteArrayUserSelect(ref err);


if (err != "")






{


MessageBox.Show(err);


err = "";


return null;


}


// 反序列化的过程


MemoryStream ms = new MemoryStream(bUserData);


IFormatter bf = new BinaryFormatter();


object obj = bf.Deserialize(ms);


DataSet dsResult = (DataSet)obj;


//


ms.Close();


return dsResult;


}

同样一台机器,手工生成12000条数据,在本地使用WebService分别读取、传输并在客户端显示数据集和byte[]格式的数据,前者平均时间2.3秒,后者平均时间为1.7秒,之间的差别仅在传输过程的格式,还有后者需要的序列化和反序列化的时间.本地WebService传输的差别尚且如此,通过网络传输的时间优化自然会更明显..

.net1.1下面微软提供的DataSetSurrogate开发包下载地址:http://support.microsoft.com/default.aspx?scid=kb;en-us;829740 DataSetSurrogate 在.net 2.0里自带
在.net1.1下的实现方式实例如下


在这里,有两种方式:可把序列化后的数据用文件形式保存在客户端硬盘;也可用Byte[]方式传回客户端,以下是代码。


web service 端(文件形式)




[WebMethod(Description="循环获取远程DATASET")]


public void SurrogateReadTable(string TableName)






{


//把DataSet通过Surrogate Class 序列化成 Binary Stream




DataSet ds;


ds=SqlHelper.ExecuteDataset(cnn,CommandType.Text,"select * from "+TableName);


//实例化DataSetSurrogate,传取出的DATASET到构造函数里


sds = new DataSetSurrogate(ds);


//实例化二进制流


BinaryFormatter bf=new BinaryFormatter();


StreamWriter swDat;


//写到本地一个文件里


swDat = new StreamWriter(@"c:/output_surrogate_dataset.dat");


bf.Serialize(swDat.BaseStream, sds);


//这里可以知道序列化后的文件的大小


long size = swDat.BaseStream.Length;


swDat.Close();




}




客户端




private void button1_Click(object sender, System.EventArgs e)






{


label1.Text=DateTime.Now.ToString();




button1.Enabled=false;


//反序列化Binary Stream能通过Surrogate Class转换成 DataSet




//从WEB SERVICE上读取方法


svs.SurrogateRead("t_busdocbase");


BinaryFormatter bf=new BinaryFormatter();


StreamReader swDat;


swDat = new StreamReader(@"c:/output_surrogate_dataset.dat");


object o=bf.Deserialize(swDat.BaseStream);


DataSet ds;


sds = (DataSetSurrogate) o;


ds = sds.ConvertToDataSet();


dataGrid1.DataSource=ds.Tables[0];


swDat.Close();


}








web service 端(Byte[]方式)




[WebMethod(Description="获取业务资料远程DATASET")]


public byte[] SurrogateRead1()






{


DataSet ds;


ds=SqlHelper.ExecuteDataset(cnn,CommandType.Text,"select * from t_busdocbase");


sds = new DataSetSurrogate(ds);


MemoryStream s= new MemoryStream();


BinaryFormatter bf = new BinaryFormatter();


bf.Serialize(s,sds);




byte[] e = s.ToArray();


return e;




}






客户端




private void button3_Click(object sender, System.EventArgs e)






{


label1.Text=DateTime.Now.ToString();




button3.Enabled=false;


//*反序列化Binary Stream能通过Surrogate Class转换成 DataSet*/




//从WEB SERVICE上读取方法






byte [] bb=svs.SurrogateRead1();


MemoryStream br=new MemoryStream(bb);


BinaryFormatter bf=new BinaryFormatter();


object o=bf.Deserialize(br);


sds = (DataSetSurrogate) o;


ds = sds.ConvertToDataSet();


dataGrid1.DataSource=ds.Tables[0];




br.Close();




}




我个人觉得用byte[]方式会安全些,毕竟不用在客户端产生文件,不用担心数据的安全。





在2.0 中对数据集序列化和反序列化的方法进行了一下简单的封装,使其可以得到重用的效果.见下面的类DatFormatter.

通过GetBinaryFormatData方法可以转换数据集为二进制,在服务器端使用,转换数据集格式。发送,客户端接收,得到二进制格式数据,使用RetrieveDataSet方法,反序列化,得到数据集,进行客户端操作。通过这些简单的操作(序列化和反序列化,将数据压缩),可以使数据集等体积庞大的对象在远程传递中的时间大大减少,并且可以减少网络中断等问题对程序的影响。

1

using System;
2

using System.IO;
3

using System.Data;
4

using System.Runtime.Serialization;
5

using System.Runtime.Serialization.Formatters.Binary;
6


7

namespace Common
8





{
9

public class DataFormatter
10





{
11



private DataFormatter()

{ }
12



/**//// <summary>
13

/// Serialize the Data of dataSet to binary format
14

/// </summary>
15

/// <param name="dsOriginal"></param>
16

/// <returns></returns>
17

static public byte[] GetBinaryFormatData(DataSet dsOriginal)
18





{
19

byte[] binaryDataResult = null;
20

MemoryStream memStream = new MemoryStream();
21

IFormatter brFormatter = new BinaryFormatter();
22

dsOriginal.RemotingFormat = SerializationFormat.Binary;
23


24

brFormatter.Serialize(memStream, dsOriginal);
25

binaryDataResult = memStream.ToArray();
26

memStream.Close();
27

memStream.Dispose();
28

return binaryDataResult;
29

}
30



/**//// <summary>
31

/// Retrieve dataSet from data of binary format
32

/// </summary>
33

/// <param name="binaryData"></param>
34

/// <returns></returns>
35

static public DataSet RetrieveDataSet(byte[] binaryData)
36





{
37

DataSet dataSetResult = null;
38

MemoryStream memStream = new MemoryStream(binaryData);
39

IFormatter brFormatter = new BinaryFormatter();
40


41

object obj = brFormatter.Deserialize(memStream);
42

dataSetResult = (DataSet)obj;
43

return dataSetResult;
44

}
45

}
46

}
47
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: