WCF DateSet应用技巧详解

开发 开发工具
WCF DateSet的操作在实际应用中起到了很重要的作用。初学者们可以在这里来详细的了解一下其中的相关操作技巧,来帮助我们解决相关问题。

WCF开发工具是.NET Framework 3.5中的一个重要的组成部分,我们可以通过它的帮助来实现许多需求。在这里我们可以先来了解一下WCF DateSet的相关概念,希望可以帮助我们来解决一些问题。

这几天看了WCF相关的资料,然后就产生一个想法.如何实现WCF实现传输DataSet,这个服务的主要功能是客户端调用服务端的一个函数,这个函数接受一个DataSet的参数,然后再返回一个DataSet,当然这个功能很简单,几行代码就搞定了.可是当如果DataSet内的数据量非常大的时候,那就麻烦了.(暂不讨论传输大数据量的DataSet是否合理),WCF默认最大传输数据量为64K,当然可以实现修改配置文件来传输大数据量,可是不能解决本质的问题,我目前解决这个问题的方式是,把一个DataSet序列化为一个字节,然后把这些字节进行压缩,然后每次发送一小段字节回去,接受到这个些字节以后然后在解压缩,再反序列化为为DataSet,这样就实现了,传入一个WCF DateSet然后再返回一个DataSet,这样的话,就需要用到WCF的双向通信,使用回调函数。

  1. DuplexChannelFactory<IHello> channelFactory = new DuplexChannelFactory
    <IHello>(new InstanceContext(new ClientCallBack()), "defaultEndpoint");  
  2. IHello getHello = channelFactory.CreateChannel();  
  3. //传入DataSet到服务端  
  4. getHello.SayHelloTo();  
  5. 首先客户端调用服务端的函数SayHelloTo(),  
  6. public void SayHelloTo()  
  7. {  
  8. //读取客户端传入的WCF DateSet  
  9. #region 服务端的数据  
  10. ICallback callback = OperationContext.Current.GetCallbackChannel
    <ICallback>();  
  11. int intNum = callback.getTimes() + 1; //获取读取字节流的次数  
  12. MemoryStream Mstream = new MemoryStream();  
  13. byte[] getbyte;  
  14. for (int i = 1; i < intNum; i++)  
  15. {  
  16. getbyte = callback.getBytes(i);  
  17. Mstream.Write(getbyte,0,getbyte.Length);//写到内存中  
  18. }  
  19. Mstream.Position = 0;  
  20. getbyte = new byte[Mstream.Length];  
  21. Mstream.Read(getbyte, 0, getbyte.Length);//从内存中读到getbyte中  
  22. Mstream.Close();  
  23. //反序列化  
  24. ServiceData = KCDataFormatter.RetrieveDataSetDecompress(getbyte);  
  25. //----------------------------  
  26. //此处得到序列化以后的字节,可以再反序列化为DataSet,
    得到DataSet就可以对个DataSet做处理,删除,修改,  
  27. //处理完成再把处理完成的DataSet赋值给ServiceData,就可以了  
  28. //----------------------------  
  29. #endregion  
  30. }ICallback callback = OperationContext.Current.
    GetCallbackChannel
    <ICallback>();  
  31. 此时就会调用客户端的回调函数  
  32. public class ClientCallBack : ICallback  
  33. {  
  34. #region ICallBack 成员  
  35. //要上传的数据  
  36. public void getData()  
  37. {  
  38. DataSet ds = new DataSet("test");  
  39. DataTable table = new DataTable("test");  
  40. DataColumn column = new DataColumn("test");  
  41. column.DataType = Type.GetType("System.String");  
  42. table.Columns.Add(column);  
  43. DataRow row;  
  44. for (int i = 0; i < 200000; i++)  
  45. {  
  46. row = table.NewRow();  
  47. row["test"] = "Hello";  
  48. table.Rows.Add(row);  
  49. }  
  50. ds.Tables.Add(table);  
  51. byte_All = KCDataFormatter.GetBinaryFormatDataCompress(ds);  
  52. }  
  53. private int i = 1000; //每次读取字节的数量  
  54. byte[] byte_All;//获取要上传的字节流  
  55. MemoryStream Mstream;//流  
  56. public byte[] getBytes(int intNum)  
  57. {  
  58. int j = 1000;  
  59. byte[] buffer;  
  60. if (intNum < iti) //判断是否是最后一次循环  
  61. {  
  62. buffer = new byte[1000];  
  63. }  
  64. else  
  65. {  
  66. int nn = byte_All.Length - ((iti - 1) * 1000);  
  67. buffer = new byte[nn];  
  68. j = nn;  
  69. }  
  70. int iold = (i * (intNum - 1)); //记录上一次的字节位置  
  71. Mstream = new MemoryStream();  
  72. Mstream.Write(byte_All, iold, j);//从byte_All中
    的第iolld开始写入j(最多不超过)个到内存中  
  73. buffer = Mstream.ToArray();  
  74. Mstream.Close();  
  75. Mstream.Dispose();  
  76. return buffer;  
  77. }  
  78. private int iti = 0; //初始化循环次数  
  79. public int getTimes() //将数据流分为多少部分  
  80. {  
  81. getData();  
  82. int temp = byte_All.Length / 1000;  
  83. int intNum = byte_All.Length % 1000 != 0 ? temp + 1 : temp;  
  84. iti = intNum;  
  85. return intNum;  
  86. }  
  87. #endregion  

getData()函数内可以编写需要上传的WCF DateSet,我这里是生成20W条记录.通过回调函数就会把这20W条数据传入服务端,回调结束了,DataSet也就传入了服务端了.(我这里服务端没有任何处理这个DataSet就直接返回这个DataSet会客户端),客户端继续执行他的逻辑,此时的逻辑是把刚才传入的服务端的Dataset再返回给客户端

  1. //获取服务端返回的DataSet  
  2. int intNum = getHello.serviceTime() + 1; //获取读取字节流的次数  
  3. MemoryStream Mstream = new MemoryStream();  
  4. byte[] getbyte;  
  5. for (int i = 1; i < intNum; i++)  
  6. {  
  7. getbyte = getHello.DownByte(i);  
  8. Mstream.Write(getbyte, 0, getbyte.Length);//写到内存中  
  9. }  
  10. Mstream.Position = 0;  
  11. getbyte = new byte[Mstream.Length];  
  12. Mstream.Read(getbyte, 0, getbyte.Length);//从内存中读到getbyte中  
  13. Mstream.Close();  
  14. //反序列化  
  15. DataSet ds = KCDataFormatter.RetrieveDataSetDecompress(getbyte); 

这里就得到了服务端返回的WCF DateSet.全部代码已经打包,vs2008中文版编译通过!

【编辑推荐】

  1. WCF获取客户端IP应用经验分享
  2. WCF元数据应用方法介绍
  3. PDA访问WCF具体步骤浅析
  4. WCF Stream正确应用指南
  5. WCF上传文件解决方案剖析
责任编辑:曹凯 来源: 博客园
相关推荐

2010-02-25 11:23:29

WCF返回自定义格式

2010-02-22 16:26:47

WCF传输数据

2010-02-22 16:19:25

WCF自托管

2010-03-01 13:06:49

WCF继承

2010-02-25 09:50:30

WCF路由截获消息

2009-12-21 14:49:27

2010-02-25 15:25:19

WCF通道

2010-02-22 17:21:02

WCF消息交换

2010-02-22 15:20:54

WCF WS-Disc

2010-02-23 14:17:20

WCF配置文件

2010-02-25 10:52:29

WCF响应服务

2010-02-22 13:28:05

WCF异步调用

2010-02-22 17:51:46

WCF传较大数据

2009-12-21 18:10:50

WCF实现事件通知

2010-02-26 13:40:28

WCF消息头

2010-02-23 13:03:34

WCF序列化

2010-03-01 16:04:31

WCF服务契约

2010-02-26 10:46:12

WCF行为扩展

2010-03-02 10:50:57

WCF元数据交换

2010-02-25 16:45:13

WCF应用技巧
点赞
收藏

51CTO技术栈公众号