WCF开发工具是.NET Framework 3.5中的一个重要的组成部分,我们可以通过它的帮助来实现许多需求。在这里我们可以先来了解一下WCF DateSet的相关概念,希望可以帮助我们来解决一些问题。
这几天看了WCF相关的资料,然后就产生一个想法.如何实现WCF实现传输DataSet,这个服务的主要功能是客户端调用服务端的一个函数,这个函数接受一个DataSet的参数,然后再返回一个DataSet,当然这个功能很简单,几行代码就搞定了.可是当如果DataSet内的数据量非常大的时候,那就麻烦了.(暂不讨论传输大数据量的DataSet是否合理),WCF默认最大传输数据量为64K,当然可以实现修改配置文件来传输大数据量,可是不能解决本质的问题,我目前解决这个问题的方式是,把一个DataSet序列化为一个字节,然后把这些字节进行压缩,然后每次发送一小段字节回去,接受到这个些字节以后然后在解压缩,再反序列化为为DataSet,这样就实现了,传入一个WCF DateSet然后再返回一个DataSet,这样的话,就需要用到WCF的双向通信,使用回调函数。
DuplexChannelFactory<IHello> channelFactory = new DuplexChannelFactory
<IHello>(new InstanceContext(new ClientCallBack()), "defaultEndpoint");
IHello getHello = channelFactory.CreateChannel();
//传入DataSet到服务端
getHello.SayHelloTo();
首先客户端调用服务端的函数SayHelloTo(),
public void SayHelloTo()
{
//读取客户端传入的WCF DateSet
#region 服务端的数据
ICallback callback = OperationContext.Current.GetCallbackChannel
<ICallback>();
int intNum = callback.getTimes() + 1; //获取读取字节流的次数
MemoryStream Mstream = new MemoryStream();
byte[] getbyte;
for (int i = 1; i < intNum; i++)
{
getbyte = callback.getBytes(i);
Mstream.Write(getbyte,0,getbyte.Length);//写到内存中
}
Mstream.Position = 0;
getbyte = new byte[Mstream.Length];
Mstream.Read(getbyte, 0, getbyte.Length);//从内存中读到getbyte中
Mstream.Close();
//反序列化
ServiceData = KCDataFormatter.RetrieveDataSetDecompress(getbyte);
//----------------------------
//此处得到序列化以后的字节,可以再反序列化为DataSet,
得到DataSet就可以对个DataSet做处理,删除,修改,
//处理完成再把处理完成的DataSet赋值给ServiceData,就可以了
//----------------------------
#endregion
}ICallback callback = OperationContext.Current.
GetCallbackChannel<ICallback>();
此时就会调用客户端的回调函数
public class ClientCallBack : ICallback
{
#region ICallBack 成员
//要上传的数据
public void getData()
{
DataSet ds = new DataSet("test");
DataTable table = new DataTable("test");
DataColumn column = new DataColumn("test");
column.DataType = Type.GetType("System.String");
table.Columns.Add(column);
DataRow row;
for (int i = 0; i < 200000; i++)
{
row = table.NewRow();
row["test"] = "Hello";
table.Rows.Add(row);
}
ds.Tables.Add(table);
byte_All = KCDataFormatter.GetBinaryFormatDataCompress(ds);
}
private int i = 1000; //每次读取字节的数量
byte[] byte_All;//获取要上传的字节流
MemoryStream Mstream;//流
public byte[] getBytes(int intNum)
{
int j = 1000;
byte[] buffer;
if (intNum < iti) //判断是否是最后一次循环
{
buffer = new byte[1000];
}
else
{
int nn = byte_All.Length - ((iti - 1) * 1000);
buffer = new byte[nn];
j = nn;
}
int iold = (i * (intNum - 1)); //记录上一次的字节位置
Mstream = new MemoryStream();
Mstream.Write(byte_All, iold, j);//从byte_All中
的第iolld开始写入j(最多不超过)个到内存中
buffer = Mstream.ToArray();
Mstream.Close();
Mstream.Dispose();
return buffer;
}
private int iti = 0; //初始化循环次数
public int getTimes() //将数据流分为多少部分
{
getData();
int temp = byte_All.Length / 1000;
int intNum = byte_All.Length % 1000 != 0 ? temp + 1 : temp;
iti = intNum;
return intNum;
}
#endregion
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
getData()函数内可以编写需要上传的WCF DateSet,我这里是生成20W条记录.通过回调函数就会把这20W条数据传入服务端,回调结束了,DataSet也就传入了服务端了.(我这里服务端没有任何处理这个DataSet就直接返回这个DataSet会客户端),客户端继续执行他的逻辑,此时的逻辑是把刚才传入的服务端的Dataset再返回给客户端
//获取服务端返回的DataSet
int intNum = getHello.serviceTime() + 1; //获取读取字节流的次数
MemoryStream Mstream = new MemoryStream();
byte[] getbyte;
for (int i = 1; i < intNum; i++)
{
getbyte = getHello.DownByte(i);
Mstream.Write(getbyte, 0, getbyte.Length);//写到内存中
}
Mstream.Position = 0;
getbyte = new byte[Mstream.Length];
Mstream.Read(getbyte, 0, getbyte.Length);//从内存中读到getbyte中
Mstream.Close();
//反序列化
DataSet ds = KCDataFormatter.RetrieveDataSetDecompress(getbyte);
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
这里就得到了服务端返回的WCF DateSet.全部代码已经打包,vs2008中文版编译通过!
【编辑推荐】