我继承了这个庞大的应用程序,包括客户端和服务器代码,我正在尝试将部分通信的传输模式更改为“流式”,以避免在缓冲模式下可能发生的浪费的内存消耗使我的客户端抛出OOM异常,另请参阅this answer。
代码如下:
GZipMessageEncodingBindingElement gElement = new GZipMessageEncodingBindingElement();
HttpsTransportBindingElement hElement = new HttpsTransportBindingElement();
hElement.TransferMode = TransferMode.Streamed;
hElement.MaxBufferSize = int.MaxValue;
hElement.MaxBufferPoolSize = int.MaxValue;
hElement.MaxReceivedMessageSize = int.MaxValue;
CustomBinding binding = new CustomBinding();
binding.SendTimeout = new TimeSpan(0, 0, 60);
binding.Elements.Add(gElement);
binding.Elements.Add(hElement);
EndpointAddress address = new EndpointAddress(uri);
return new ChannelFactory<T>(binding, address).CreateChannel();
异常是一个TimeoutException,它建议我增加SendTimeout(当前设置为1分钟)。
更新但是,在将transferMode设置为流式传输后,有2个服务仍然有效,我实际上已确认他们通过在GZIPMessageEncoder.ReadMessage中设置断点来使用GZIP / HTTPS(Stream,... )。因此,对于2个服务,它在ReadMessage内部中断,对于一个服务它不会。据我所知,当涉及到ConcurrencyMode和InstanceContextMode时,服务的配置相同。
更新2:在仅配置一个似乎不作为流式传输的服务并将其他两个服务缓冲后,它部分工作。所以不是服务本身就是坏的,也许某些连接会阻碍流模式中的其他连接,使它们超时。
如果我只删除'TransferMode'行,一切都很好,测试服务器永远不需要超过一秒左右的时间来响应,所以只是增加SendTimeout不会导致任何地方。
对于这个测试,我只更改了客户端btw。就我的理解而言,这个设置不应该影响客户端和服务器的通信方式,只是具有“流式”设置的应用程序处理数据的方式。
对我来说很容易,我是一个完整的WCF新手,虽然我在MSDN页面上看到了一些关于流传输模式的注意事项,但是在我的代码/配置中指向grep的指针会非常有帮助,否则它只是巨大的,许多服务,每个服务都有不同的传输设置等。
谢谢!
答案 0 :(得分:0)
我无法确切地找出问题的原因,但我能够通过执行以下操作来解决问题并消除过多的内存消耗等。
在摆脱GzipMessageEncoder之后(请参阅wcf conditional compression了解如何通过IIS'内置压缩替换它),这是一个怪物(请参阅我在WCF HttpTransport: streamed vs buffered TransferMode上的回答),很容易切换到流式传输TransferMode:How can I prevent BufferManager / PooledBufferManager in my WCF client app from wasting memory?。