[讨论]讨厌或不懂WCF的进

qldsrx 2013-04-04 09:04:35
加精
Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,其功能非常丰富。有人讨厌并反对使用它,其理由无非是效率低。我在这里推荐学习它,但最终是否使用不表态。
WCF效率低下的原因主要是序列化的问题。WCF默认采用XML序列化,而用来发送消息之前,必须先将对象进行第一次XML序列化,包装到Message类型中去,然后使用指定的序列化类进行第二次序列化(格式化)。为什么说它进行了2次序列化呢,因为我断点跟踪自定义绑定类进去看过,同时那个NetDataContractSerializer继承“XmlObjectSerializer,IFormatter”也是最好的证明,即使替换其它序列化类,也必须继承那个抽象类和接口,第二次序列化类似格式化。
另外WCF序列化后的内容是非常庞大的,导致了传输过程浪费带宽。
但是WCF却是值得学习的,因为那个为我们考虑了很多通讯方面的设定,比如各种超时、传输模式、缓存大小、REST风格等,即使自己用Socket来写,借鉴WCF的好的地方也是非常值得的,因此不能否定WCF。

对于WCF效率低下,我考虑过很多方案,也在网上搜索过很多资料,最终只能用妥协的方法处理,就是修改返回值类型为Stream。如此一来,序列化过程自己控制,只需要序列化一次即可。之后虽然WCF会对Stream也进行包装,但是不会再次序列化,仅仅是进行了普通的流读取操作。这样做的另一个好处是,可以使用第三方的序列化类进行序列化,大大减少序列化后产生的数据量,减少网络带宽的消耗。不过缺点也很明显,就是返回值类型无法直接推断了,不直观,但比起直接用Socket还是好理解多了。

对于返回值类Stream的情况,如果WCF同时启用了Streamed模式传输,还可以通过构造无缓存流来实现真正的无缓存数据返回。多数情况下,要无缓存返回流是不可能的,必须要构造一个MemoryStream,然后把数据都写入其中,再通过函数返回,当然直接返回FileStream也可以,但是先序列化到文件中的话,速度自然会降低。因此要实现序列化和网络发送同步进行,这看似只有Socket直接编程才能做到,不过利用流特性也是可以实现的,有关无缓存流,下次分解。
...全文
14598 145 打赏 收藏 转发到动态 举报
写回复
用AI写文章
145 条回复
切换为时间正序
请发表友善的回复…
发表回复
有点Bugs 2014-05-04
  • 打赏
  • 举报
回复
wcf对于大数据量的序列化真是太蛋疼了
fire_fire_fire 2014-03-13
  • 打赏
  • 举报
回复
学习了,感谢各位
ttgss 2013-10-17
  • 打赏
  • 举报
回复
siaosa fangxinggood 等前辈 什么是webapi啊. 哪位大哥有这方面的介绍啊..
kiba518 2013-06-20
  • 打赏
  • 举报
回复
我还真做了100W行以上的WCF传输 貌似挺快的30秒以内搞定
xiaoyan21 2013-06-20
  • 打赏
  • 举报
回复
我是新手 点有疑问,楼主说"返回值类型为Stream,大大减少序列化后产生的数据量" ,我测试后发现并非如此。 返回Stream类型的数据量 比 返回DataTable 的数量据要多出1/3啊. 感觉Stream类型是要二次序列化,DataTable是需一次序列化. 也许是我的代码不对。 楼主怎么实现的?能发点代码看看吗?
qldsrx 2013-06-04
  • 打赏
  • 举报
回复
引用 135 楼 wyd1520 的回复:
作过对比用WCF与直接用Socket 转输同样的数据 像 int int bool int 这样的数据 Wcf转的量是Socket的10倍甚至更多... 他中间有了序列化,这个序列化很可怕如果只转 int int bool int Socket只转13个字节 Wcf。。就不一定了平常我们定义一个实体,然后这个实体支持可序列化。。。试了一下,定义int int bool int这四个属性,序列化后。达到1两百个字节。。。不知楼主有没有什么好的方法。。。。
一、尽量使用Json序列化替代XML序列化,Json序列化在传输这类基本数据类型时产生的数据量非常小,XML序列化因为要附带很多xml命名空间在标签中,所以占了很大的体积,而且xml是前后对称标签,一个属性名要出现2次,Json只出现一次。 二、可以使用第三方序列化类,去掉Json序列化中的type属性说明,可以大大减少数据量,副作用是反序列化时必须指定实际类型,无法通过Json字符串来推测数据类型。
wjy217213 2013-06-04
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
WCF不是不好用,是效率有时候不给力,它的安全可靠还是很给力的 LZ推荐的资源确实很不错
nikolay 2013-06-04
  • 打赏
  • 举报
回复
关键还是要看用在什么地方 对于快速开发、中低数据并发和数据量来说是非常合适的。 对于大数据并发肯定是要针对不同的业务情况进行优化的。
本拉灯 2013-05-31
  • 打赏
  • 举报
回复
引用 楼主 qldsrx 的回复:
Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,其功能非常丰富。有人讨厌并反对使用它,其理由无非是效率低。我在这里推荐学习它,但最终是否使用不表态。 WCF效率低下的原因主要是序列化的问题。WCF默认采用XML序列化,而用来发送消息之前,必须先将对象进行第一次XML序列化,包装到Message类型中去,然后使用指定的序列化类进行第二次序列化(格式化)。为什么说它进行了2次序列化呢,因为我断点跟踪自定义绑定类进去看过,同时那个NetDataContractSerializer继承“XmlObjectSerializer,IFormatter”也是最好的证明,即使替换其它序列化类,也必须继承那个抽象类和接口,第二次序列化类似格式化。 另外WCF序列化后的内容是非常庞大的,导致了传输过程浪费带宽。 但是WCF却是值得学习的,因为那个为我们考虑了很多通讯方面的设定,比如各种超时、传输模式、缓存大小、REST风格等,即使自己用Socket来写,借鉴WCF的好的地方也是非常值得的,因此不能否定WCF。 对于WCF效率低下,我考虑过很多方案,也在网上搜索过很多资料,最终只能用妥协的方法处理,就是修改返回值类型为Stream。如此一来,序列化过程自己控制,只需要序列化一次即可。之后虽然WCF会对Stream也进行包装,但是不会再次序列化,仅仅是进行了普通的流读取操作。这样做的另一个好处是,可以使用第三方的序列化类进行序列化,大大减少序列化后产生的数据量,减少网络带宽的消耗。不过缺点也很明显,就是返回值类型无法直接推断了,不直观,但比起直接用Socket还是好理解多了。 对于返回值类Stream的情况,如果WCF同时启用了Streamed模式传输,还可以通过构造无缓存流来实现真正的无缓存数据返回。多数情况下,要无缓存返回流是不可能的,必须要构造一个MemoryStream,然后把数据都写入其中,再通过函数返回,当然直接返回FileStream也可以,但是先序列化到文件中的话,速度自然会降低。因此要实现序列化和网络发送同步进行,这看似只有Socket直接编程才能做到,不过利用流特性也是可以实现的,有关无缓存流,下次分解。
BinayWrite(Stream)进行数据封装 定义C/S 之间的收发协议 WCF按你说的只收发Stream 类拟写Socket C/S收发协议一样 C发送 Write(int) Write(bool) Write(string) S接收 ReadInt ReadBool ReadString
本拉灯 2013-05-31
  • 打赏
  • 举报
回复
作过对比用WCF与直接用Socket 转输同样的数据 像 int int bool int 这样的数据 Wcf转的量是Socket的10倍甚至更多... 他中间有了序列化,这个序列化很可怕如果只转 int int bool int Socket只转13个字节 Wcf。。就不一定了平常我们定义一个实体,然后这个实体支持可序列化。。。试了一下,定义int int bool int这四个属性,序列化后。达到1两百个字节。。。不知楼主有没有什么好的方法。。。。
我要坚强 2013-05-31
  • 打赏
  • 举报
回复
引用 102 楼 qldsrx 的回复:
[quote=引用 99 楼 WPAPA 的回复:] 引用 98 楼 WPAPA 的回复:从来没打算过用wcf,毕竟这玩意就是拿来给懒得自己写socket的人,不懂socket的人用的,微软的定位也是方便快速开发的,所以lz完全不用纠结效率问题了,因为这东西本身设计出来也不是为了解决效率问题的 所以想要写出好东西,还是需要了解底层实现的呀,微软这种降低学习成本的办法虽然有可取之处,但是就没法保证效率了,囧 ……
你的观点说明你不了解WCF,微软的定位绝对不是快速开发,更不是给懒人使用。微软的东西向来是提供了一个简单的入门级和一个超级复杂的提高级,WCF要提高太难了,要阅读大量资料,最气人的是还受到条条框框的限制。[/quote] + 提高有点头痛资料不好找
showjim 2013-05-31
  • 打赏
  • 举报
回复
欢迎楼主使用一下最新版本的fastCSharp的TCP调用或者TCP服务,希望你能提出一些存在的问题或者建议,谢谢!
stillwawagi 2013-05-31
  • 打赏
  • 举报
回复
刚好遇到问题了 http://bbs.csdn.net/topics/390476241 各路大牛帮个忙
大腹 2013-05-02
  • 打赏
  • 举报
回复
个人感觉 wcf遵循ws-*的各种范式,所以一些消息头避免不了。 正如楼主所分析,我们可以对于信息主体进行压缩格式化,实际上应该已经满足了我们的需要,毕竟信息主体才是我们需要传递的数据,也是最占空间的。
508938326 2013-04-25
  • 打赏
  • 举报
回复
留个脚印。
jy251 2013-04-25
  • 打赏
  • 举报
回复
引用 1 楼 Chinajiyong 的回复:
如果传递的数据量不大,传递时间很短,基本不影响。 但是传递数据量大(比如传递多媒体数据等),传递时间会很长,要阻塞客户端进程
赞同LZ和引用的老兄的观点 我是实实在在用过序列化来传输数据的,我发现数据量大于200多MB的时候,序列化就失败。。。至今未弄懂是为什么。 传输的数据量过大,是会严重堵塞服务器传送资源的,每次我写的一个上传文件线程上传100多MB数据的时候,我其他的线程就几乎接收不到socket的数据了,往往造成延时。
theillusion 2013-04-21
  • 打赏
  • 举报
回复
引用 40 楼 qldsrx 的回复:
场景三:服务器只有4G内存,但是为了缓存部分请求结果,内存不能随便浪费。如果用默认的消息处理方式,对象本身占一份内存、序列化到Message后再占一份内存、发送数据又占一份内存。如果数据量大,发送耗时长,内存暂留时间偏长,服务器内存消耗严重。如果把第二份内存省略,第三份内存占有也压缩,只有对象本身占用内存,而那部分又可以作为缓存来使用,下次请求直接读取而不访问数据库,充分利用服务器内存资源,做到不浪费,否则再大的内存都不够用。反对频繁调用GC.Collect()来释放内存。
缓存和 GC 有什么关系?这段描述给我的感觉是,楼主在内存里缓存了大量的对象,并且当下次请求到来时,有大量数据可以在缓存中找到。不知道楼主面对的是什么性质的行业,按照我浅陋的经验,大多数应用程序中,都只有少量时效性不强的对象才适合在内存里长时间缓存。
theillusion 2013-04-21
  • 打赏
  • 举报
回复
引用 39 楼 qldsrx 的回复:
场景二:并发数100的情况并不少见。如果没个请求返回1000左右的数据条数,那么10W就有了,如果数据提及是100M那么光网络上传输都要几分钟时间,但是如果数据量压缩到原来的1/10,那就只要几十秒时间,大大提高了数据响应速度和降低并发冲突。
楼主的服务器网络带宽是怎么样的,50K?如果程序经常要处理楼主所说的那么大的数据量的话,该升升级了
theillusion 2013-04-21
  • 打赏
  • 举报
回复
引用 39 楼 qldsrx 的回复:
场景一:前人写了个C/S系统,直连数据库的,每个位置一个数据库,但是互相间数据需要同步,自带的同步工具经常出错,遇到几千资料要同步的时候,同步几个小时都不会好,当然上行才50K,但是要时时同步数据没办法,用WCF代替吧,那个序列化后的数据不减少体积一样会很慢。 当然,对于ADSL来说,需要数据库信息交换的时候,50K上传显然不够,必须考虑压缩数据量。不然别说10W了,1W就可以崩溃。
同步问题,不知道是需要将一个点的变更同步到多个其它点,还是将多个点的变更同步到一个点。建议看看sql复制,sync framework。不管怎样,在传输方面,涉及大数据量时,不适合用WCF。
加载更多回复(105)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧