我一直在为我们的WPF应用程序遇到问题而苦苦挣扎几天,我想知道是否有人之前遇到过此问题并且可以提供帮助? 问题似乎归结为客户端生成“即时”序列化程序来处理该Web方法调用中的类型。当第一次调用该方法时(Web服务本身已经运行),可能需要例如8秒,后续通话可能需要20毫秒。在此延迟期间,客户端WPF进程上的CPU为v。高。
使用XmlSerializer时,有一种方法可以使用svcutil预生成这些序列化程序集。当(正如我们)使用普通的WCF DataContractSerializer时,此选项似乎不存在。
我想要的是能够为我的所有数据合同(很多)中的所有类型预生成此程序集,或者替换为使用我可以编码并传递数据的自定义程序替换此流程二进制(我们拥有这个webservice / client的两端,它们都是.NET 4)。我已经使用了BinaryForamtter和GZip压缩,虽然这加速了数据的传输,但它总是被恢复为XML以被框架反序列化,因此这个问题仍然存在。
有什么想法吗?
答案 0 :(得分:8)
你可以使用像protobuf-net这样的二进制库,它很快,即使有初始启动成本,因为必须为每种类型生成代码,它仍然是way better than DataContractSerializer
or BinaryFormatter
。您应该获得几秒钟,并获得整体更顺畅的体验。它可以是easily integrated with WCF。请记住,WCF仍将检查您的各种合同,以生成正确的WSDL和各种元数据。
还有其他一些因素可能会降低WCF启动速度,例如确定默认Web代理。如果您对绑定配置没有任何用处,请确保useDefaultWebProxy
为false
。
但是,无论您采取什么措施来优化它,您都会发现WCF启动通常很慢。就个人而言,厌倦了类似场景中的缓慢战斗(我控制了两端,客户端是WPF应用程序),我只是放弃了WCF并转向了ServiceStack + protobuf-net。第一个呼叫从2-3秒到大约100毫秒,所有后续的HTTP呼叫都是即时的。整体用户体验有了很大改善。请注意,我与ServiceStack没有任何关系,这只是我的经验。
答案 1 :(得分:2)
您是否通过查看生成的服务引用确认DataContractSerializer确实正在使用?由于在“添加服务引用”操作期间某些模式不匹配,可能会生成XmlSerializer代码而不是默认的DataContractSerializer,这会导致此行为是XmlSerializer的典型行为。在这种情况下,如您所述 - 您可以预先生成序列化代码以改进冷启动:http://msdn.microsoft.com/en-us/library/aa751883.aspx。 谢谢。
答案 2 :(得分:0)
您可以通过预加载WCF服务来改善冷启动时间......即。不要等待第一个请求导致它被加载...提前加载。
只是一些想法......“可能”有助于加速序列化领域的事情。
关于为您的服务类型预生成序列化程序集.... Project | Build中有一个名为“Generate Serialization Assembly”的选项....如果切换为“On”,那么它会在Build中生成程序集时间而不是在运行时动态。
目前尚不清楚此选项是否仅适用于基于XMLSerializer的序列化程序或DataContractSerializers的预生成序列化程序集。您可以尝试将其切换为“开”以查看它是否有所作为。
您也可以尝试在客户端和服务器的代码中尽早执行此操作,以运行DataContract序列化程序...即。在客户端或服务器必须处理请求之前......(不确定它是否有帮助)。
DataContractSerializer ps = new DataContractSerializer(typeof(Person));
DataContractSerializer cs = new DataContractSerializer(typeof(Company));
etc...
为了使其更易于维护,您可以编写一个使用反射来定位您要序列化的类型的例程,例如寻找标有DataContract ....或其他一些启发式......或预定义表格的类型。