[讨论]讨厌或不懂WCF的进
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直接编程才能做到,不过利用流特性也是可以实现的,有关无缓存流,下次分解。 --------------------编程问答-------------------- 如果传递的数据量不大,传递时间很短,基本不影响。
但是传递数据量大(比如传递多媒体数据等),传递时间会很长,要阻塞客户端进程 --------------------编程问答-------------------- 不知道楼主是怎么用的,一般来讲性能瓶颈在数据库上,而不在网络传输上,追求 WCF 的性能似乎意义不大 --------------------编程问答-------------------- LZ这种以Stream流处理也是对大量消息数据传递处理的一种解决方案 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- WCF做做300以下并发量的应用可以用用。做高并发,高吞吐量的程序,最好不要选这个。 否则再多钱都不够烧。 呵呵,经验之谈。 --------------------编程问答-------------------- 我更讨厌必须明确返回值类型这点 现在只能用Json数据做返回值 在SL前端解析 很是不爽 --------------------编程问答-------------------- 这方面的我确实不懂,学习了。 --------------------编程问答--------------------
局域网内使用直接连接数据库的方式就可以了。
一般使用wcf是广域网。
wcf是网络拥堵的时候,效果真的不是很好。
wcf没有深入研究。自己做的wince上的程序比较多。所以自己写了一套通信协议。
http://www.cnblogs.com/dataexcel/archive/2012/12/09/2809045.html --------------------编程问答-------------------- 还是喜欢使用Socket, 虽然WCF相当方便. --------------------编程问答-------------------- 另外,WCF的定位并不是单纯的数据交换或者是消息传递.
在EAI中项目中使用WCF, 才可以更好更全面的诠释WCF的优雅. --------------------编程问答-------------------- --------------------编程问答-------------------- 确实不懂,学习了 --------------------编程问答--------------------
中国的网络条件不乐观啊,上行带宽能有个10M已经很不错了,如果服务端上传量很大,肯定来不及处理,而对于数据库的瓶颈几乎可以忽略,一来可以使用缓存,对经常访问的数据存放到内存里;二来可以使用IDataReader进行枚举数据发送,简单点说,就是100万行数据要发送,读取第一条就开始发送了,发送和读取是同步的。
WCF不开源和限制多是它的失败支出,设计思路很好,但是就算使用自定义绑定,能做到的也很有限,所以说那个只能用来学习,大项目要使用的话,得考虑折衷方法(自己处理序列化过程,返回stream)。
顺便补充下,其实WCF的那个序列化还有个问题,在对Dictionary进行Json序列化时,返回的格式很不爽:
[{"Key":"ID","Value":1},{"Key":"Text","Value:"gg"}]
别说看起来不爽,用起来也不方便,明明那个Key是不可能重复的,而且.NET里面不可为空(Java中可以为空),那么不是可以作为匿名类型的属性来处理吗:
{"ID":1,"Text":"gg"}
而第三方的Json序列化类对于匿名类型的序列化和反序列化,就自动映射到这样的一个Dictionary<string,string>类型上的,因此替换WCF自带的序列化类是非常有意义的。 --------------------编程问答-------------------- 受教了 感觉wcf不是很好用 --------------------编程问答-------------------- --------------------编程问答-------------------- 我没积分怎么办。 --------------------编程问答-------------------- 我是来受教育的,但是,最近的思想有点复古,感觉只有底层的才是最有效率的.... --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 我是来受教育的,但是,最近的思想有点复古,感觉只有底层的才是最有效率的.... --------------------编程问答-------------------- WCF的确性能不行,但用起来方便,真是爱恨交加,不过设计思路如楼主如说,是值得学习。因此学习WCF对设计会有一定的提高。 --------------------编程问答-------------------- 我是新人,不懂,看来还得向前辈们多了解一些,受教了 --------------------编程问答-------------------- 好贴,顶起啊 --------------------编程问答-------------------- --------------------编程问答-------------------- 只用过 几次wcf,发现 数据量大的时候传输速度会变慢,当时还不知道怎么解决......
如果以后还需要用到wcf,还得好好研究研究 --------------------编程问答-------------------- 喜欢顶 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- WCF 是工业规范,有分布式事务,有安全机制,还要考虑多种通信协议的统一编码风格,消息体自然复杂而又庞大。分久必合,合久必分,就像WebApi脱离WCF。大一统的框架未必适合所有的开发需求。 --------------------编程问答-------------------- 看看,看了要恢复才是对哦的!!!!! --------------------编程问答-------------------- --------------------编程问答--------------------
其实我是不满意微软的那个自定义绑定——CustomBinding,这里有个自定义绑定编写的示例。只能通过override进行自定义的设置,而且还必须严格遵循他给定的规范,比如他通过WrapperEncodingBindingElement替代原来的MessageEncodingBindingElement来实现消息序列化过程的控制。然后在看WrapperEncodingBindingElement类,返回MessageEncoderFactory,再通过WrapperMessageEncoderFactory返回WrapperMessageEncoder,最后由WrapperMessageEncoder对消息进行编码解码,也就是所谓的序列化。要干预序列化过程也只能在这个地方进行了。接着断点在WrapperMessageEncoder的WriteMessage方面,可以发现,无论我使用的是Json还是Xml的序列化类,最终这个参数message已经是被xml序列化后的内容了,无法再此之前进行任何干预。再看这个示例:
public override XmlObjectSerializer CreateSerializer(
Type type, XmlDictionaryString name, XmlDictionaryString ns,
IList<Type> knownTypes)
{
return new NetDataContractSerializer(name, ns);
}
要将默认的序列化替换掉,还必须返回XmlObjectSerializer的派生类,这下我彻底理解那个DataContractSerializer或DataContractJsonSerializer的使命了,与其说是序列化类,不如说是格式化类,将已经序列化到xml格式Message对象,格式化到指定类型上,从而导致了无法使用第三方快速序列化类进行替换,更不能直接实现边序列化边传递消息,因为消息本身就是已经序列化好了的。
微软在WCF编程规范中,限制死了序列化过程,只能让你改变序列化的格式Formatter,而不能直接替换序列化行为。Gzip压缩也是在格式化消息的过程中进行干预而已。微软只考虑了规范,没考虑性能,开放的自定义绑定必须遵循规范使用,无法使用Emit进行最高速度优化。.NET4.0一开始的性能迟问题导致发布延也是一个例子。
总结:C#语言本身是高效率的,但是微软的的框架却让它工作在低效率下面了,还不让别人去从根本优化它(不开源),所以我们可以学习微软的框架,实际使用就需要打上个问号。看似非常好用的内置类,反编译下看看实际是如何实现的,效率如何?只求稳定而不考虑效率的,就没必要看它的实现,微软的框架的稳定性的确是考虑的最好的。
最后推荐下一款国外著名的开源框架,对于性能追求者是个福音。其性能和灵活度都非常高,采用了Java中广泛使用的IOC思想,是替代WCF的最佳选择。(把Java的优秀思想拿来为.NET服务,又不失.NET的高效性) --------------------编程问答--------------------
无法想象用 WCF 发送100W行数据,如果楼主写了这样的代码,那很明显不是 WCF 的性能问题,而是使用不当的问题。DataContractSerializer 在控制 xml 格式方面提供的选项非常少,这是有意为之的,目的是将程序员的注意力拉回到数据契约的业务含义上,而不是物理表示上。如果很关心传输的格式,或者有大量数据要传递,那么 WCF 可能不合适。在思考怎么使用 WCF 传输几百 M 的数据时,请记住 WCF 采用的是契约优先开发方式,目的是简化跨进程跨平台调用,它不是 FTP 的替代品。 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 除 --------------------编程问答--------------------
什么叫使用不当,大数据量传输和FTP根本是两码事,如果只是传输文件,使用FileStream,无需序列化,根本不存在效率问题。但是我这里是业务需要读取数据库,比如异地数据库备份,或者业务系统通过外网访问,C/S结构访问WCF服务。数据量大是很正常的情况,如果是直连数据库,可以边度边异步加载数据,我要做的是让WCF完全替代直连数据库,使用者感觉自己就好像直连数据库。这个根本不可能用FTP替代。 --------------------编程问答-------------------- 先备份,然后传输备份文件,并且这个不是业务逻辑。除去备份数据库场景,请楼主再想想其它需要传输大量数据的例子,不需要100W条记录,10W条就可以了。 --------------------编程问答-------------------- <- 不懂wcf
最近正在学习socket,楼主能提供点资料吗 --------------------编程问答-------------------- 楼主应该是wcf方面的专家,刚好我有一个这方面的问题求解决,在论发过帖,地址如下:
http://bbs.csdn.net/topics/390408695 --------------------编程问答-------------------- 用过,不懂。。。 --------------------编程问答--------------------
场景一:前人写了个C/S系统,直连数据库的,每个位置一个数据库,但是互相间数据需要同步,自带的同步工具经常出错,遇到几千资料要同步的时候,同步几个小时都不会好,当然上行才50K,但是要时时同步数据没办法,用WCF代替吧,那个序列化后的数据不减少体积一样会很慢。
当然,对于ADSL来说,需要数据库信息交换的时候,50K上传显然不够,必须考虑压缩数据量。不然别说10W了,1W就可以崩溃。
场景二:并发数100的情况并不少见。如果没个请求返回1000左右的数据条数,那么10W就有了,如果数据提及是100M那么光网络上传输都要几分钟时间,但是如果数据量压缩到原来的1/10,那就只要几十秒时间,大大提高了数据响应速度和降低并发冲突。 --------------------编程问答-------------------- 场景三:服务器只有4G内存,但是为了缓存部分请求结果,内存不能随便浪费。如果用默认的消息处理方式,对象本身占一份内存、序列化到Message后再占一份内存、发送数据又占一份内存。如果数据量大,发送耗时长,内存暂留时间偏长,服务器内存消耗严重。如果把第二份内存省略,第三份内存占有也压缩,只有对象本身占用内存,而那部分又可以作为缓存来使用,下次请求直接读取而不访问数据库,充分利用服务器内存资源,做到不浪费,否则再大的内存都不够用。反对频繁调用GC.Collect()来释放内存。 --------------------编程问答-------------------- 除 --------------------编程问答--------------------
中国的网络条件不乐观啊,上行带宽能有个10M已经很不错了!!!!!!! --------------------编程问答-------------------- 除 --------------------编程问答--------------------
这篇帖子精华部分 --------------------编程问答-------------------- 不懂的进了 --------------------编程问答-------------------- 我开始确实有点讨厌,现在无所谓, 开始讨厌是因为感觉把html语法嵌入。 --------------------编程问答-------------------- 这方面我不懂,学习了。 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 曾经买了一本关于WCF的书 想起来还没怎么看 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 不懂来学习的说 --------------------编程问答-------------------- 来蹭点知识~~~ --------------------编程问答-------------------- 学习来的,这个wcf和socket是并列的技术?没太理解。。。。 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 不懂,长知识了 --------------------编程问答-------------------- 不懂 --------------------编程问答-------------------- WCF是.NET平台SOA架构的解决方案。
为什么说高并发的项目使用WCF不好呢? --------------------编程问答-------------------- 除 --------------------编程问答-------------------- --------------------编程问答--------------------
IOC虽然可以解决一部分问题,但是IOC的开销本身也是“很大的”,比如大量并发小数据的时候。
代码生成才能真正的高效,而且无副作用(本地调用与网络调用同在的时候)。 --------------------编程问答-------------------- 如果你要在WCF中使用Stream,同样可以使用代码生成技术,比如
public abstract class AbstractServer : IServer
{
private int Inc(int value)
{
return value + 1;
}
public abstract Stream Inc_int(Stream value);
}
生成如下代码
--------------------编程问答-------------------- --------------------编程问答-------------------- 如果想用WCF来传递大数据 那可真是选错了,跨平台、分布式 才是WCF的优势 难道你加载数据的时候会一次加载10w或者100w吗 --------------------编程问答--------------------
public class Server : AbstractServer
{
public override Stream Inc_int(Stream value)
{
int value_int = value.ToInt();//反序列化
int return_value = Inc(value_int);//调用
return return_value.ToStream();//序列化
}
}
随手写的,上面的有错误,修改一下
public inte易做图ce IServer//操作契约
{
Stream Inc_int(Stream value);
}
public abstract class AbstractServer : IServer
{
protected int Inc(int value)
{
return value + 1;
}
public abstract Stream Inc_int(Stream stream);
}
public partial class Server : AbstractServer { }
生成代理函数
public partial class Server : AbstractServer--------------------编程问答-------------------- 我讨厌WCF,不仅仅因为序列化效率低下。
{
public int Inc(int value)
{
Stream stream = value.ToStream();//序列化
Stream returnStream = Inc_int(stream);//客户端调用
return returnStream.ToInt();//反序列化
}
public override Stream Inc_int(Stream stream)
{
int value = stream.ToInt();//反序列化
int returnValue = Inc(value);//服务器端调用
return returnValue.ToStream();//序列化
}
}
操作契约就是多余的东西,因为与函数原型定义冗余了,工作量大了一倍。
另外操作契约限定了所有的操作必须集中在一个类里面,这样不仅有命名麻烦问题,很多时候又相当于重写一次函数原型定义,又一次增加了工作量。 --------------------编程问答--------------------
IOC对我来说是新概念,以前从未使用过,不过这思想的确有利于分层实现。
至于效率问题,如果真的出现了瓶颈,也不会像WCF那么难处理,因为人家是开源的,源代码都在手上了,想优化还不就是时间问题了吗? --------------------编程问答-------------------- --------------------编程问答-------------------- 改用WEB API吧. 微软已经有新欢了,不准备再把精力放在WCF上了 --------------------编程问答-------------------- 一下看成MFC了 囧大了 --------------------编程问答-------------------- 易做图尚未成功,同志们仍需努力啊 --------------------编程问答-------------------- 问题在于,socket很难吗?就算最底层的BSD socket,一月时间还学不会?用MFC或.net的socket,一周学不会?还有大量的第三方库,比如boost,libevent,libuv...随便拉出一个都不错的,如果真要学习,更推荐学boost,至少可以不受限制,你说的这个什么WC F, 相对受限一些,你不能保证让程序员一辈子只做windows开发吧,你公司产品应该也会有Linux,iOS,Android吧,为什么不把眼光放开阔一些,同样是花时间学习,直接学最有效的不是更好?
另外说说你提到的stream,从上层看,是流,从tcp以及再下一层看,就是一个一个数据包而已,看CSocket的代码,无非就是while(1){recv()},然后再分解字符串,根据数据包格式再形成流。直接看底层代码是不是理解的更清楚?比如很多人学c学不懂指针,那想想大学里的汇编内容,是不是一切都清楚不过了,不就是内存地址吗 --------------------编程问答-------------------- 存在就合理,关键看自己项目适不适合 --------------------编程问答-------------------- 我也是个新人。。不过很快会接触到WCF --------------------编程问答-------------------- wcf还真没用过。。。 --------------------编程问答--------------------
用C或者C++写网络通讯程序,只能说明你的时间浪费了不可惜。 --------------------编程问答--------------------
请问你知道什么叫做自动化吗? --------------------编程问答-------------------- 好东西,大家学习了,谢谢 --------------------编程问答--------------------
原来 asio,libevent,libev,libuv都是时间浪费了,还有什么 nginx,apache也是时间浪费了 --------------------编程问答--------------------
如果这些东西是你写的,那么请完善自动化功能,否则就是浪费别人的时间。
如果这些东西不是你写的,而这些东西不支持自动化功能,那么你的时间被别人浪费了。 --------------------编程问答--------------------
当然,就算这些东西不是你写的,而你在完善它们的自动化功能,那么你可能为别人节约了时间。
问题是C/C++能做到使用简单并且高效通用的网络调用自动化吗?如果不可以,那么你只能选择浪费自己的时间。 --------------------编程问答-------------------- WCF/ServiceStack http://www.infoq.com/articles/interview-servicestack --------------------编程问答--------------------
Good Article! --------------------编程问答-------------------- WCF不错 值得一看 这段时间一直在研究 LZ是否需要查看WCf源码呢? 我现在自定义绑定可以完成 现在想要深入 该怎么下手 --------------------编程问答-------------------- 不懂WCF
跟风讨厌WCF
随便说说
在我的想当然中
WCF只能应用于企业级内部系统的开发,例如,考勤系统啊,请假系统啊
如果在互联网级别几百万用户量的C/S上应用WCF,会死得很惨
--------------------编程问答-------------------- 除 --------------------编程问答-------------------- 正在用,WCF不要太强大,服了MS。 --------------------编程问答-------------------- 还是不懂 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 不懂WCF...只懂WCG --------------------编程问答-------------------- 不喜欢WCF,看到基于xml的序列化就觉得恶心,而且整个WCF的设计非常庞大复杂,所以自己设计了一套基于.net轻量级的分布式框架,使用二进制序列化,支持各种语言的绑定,比WCF好用多了。 --------------------编程问答-------------------- --------------------编程问答-------------------- 从来没打算过用wcf,毕竟这玩意就是拿来给懒得自己写socket的人,不懂socket的人用的,微软的定位也是方便快速开发的,所以lz完全不用纠结效率问题了,因为这东西本身设计出来也不是为了解决效率问题的 --------------------编程问答--------------------
所以想要写出好东西,还是需要了解底层实现的呀,微软这种降低学习成本的办法虽然有可取之处,但是就没法保证效率了,囧 --------------------编程问答--------------------
WCF和socket完全是2个层面的东西,这跟懒不懒没关系。WCF不好用是事实,但是你也不可能直接用socket去替代WCF,必须要在socket上做大量的工作才行。
补充:.NET技术 , C#