我们一直在客户站点看到随机的OutOfMemoryExceptions和InsufficientMemoryExceptions。我们使用GZipMessageEncoder来压缩消息。 (我知道IIS 7.x compression选项和other problems with buffering and/or the GZipMessageEncoder。)
我想尝试启用WCF流式传输。我们的WCF服务具有以下合同:
[OperationContract]
DataSet GetDataSet(Guid someGUID, string someName, DataSet parameters);
流式传输中发生的操作最多只能包含一个输入或输出参数
显然,我们的合同违反了WCF流媒体限制。该合同有3个输入参数。
然而,出于好奇,我决定尝试启用流式传输。我编辑了web.config文件和MyCSharpClient.config文件,并将以下属性插入到绑定的传输部分:
<httpTransport ... transferMode="Streamed">
令我惊讶的是,无论如何,一切似乎都有效!没有例外。我可以进入GZipMessageEncoder并验证是否正在调用流方法而不是缓冲区方法。
所以,我的问题是:为什么我能够在违反WCF输入参数限制的操作上下文中设置流传输?鉴于MSDN流媒体文章的强烈措辞,我认为这只是一个实现细节,我不能依赖这种行为。
答案 0 :(得分:2)
目前发生的情况如下:您在HTTP传输上启用了流式传输,因此传输不会缓冲任何内容 - 传输接收到Message
对象,并将其写入传输流(已包装)在XML编写器中直接。但是,操作的参数在它们被序列化之前被缓冲,因此你“支付”你将传输模式设置为'Buffered'的内存使用量。在线上,不同之处在于来自此服务的响应将被分块(即,它将具有Transfer-Encoded: chunked
标头,并且主体将相应地格式化。但是,该服务的响应将被分块(而不是具有Content-Length标头)。它也会起作用。
我会说MSDN中的文章本来可以选择更好的词。为了使利用流的操作,它需要有一个单独的参数,通常是Stream
,Message
类型或某种实现IXmlSerializable
的类型。但是一个简单的合同(即[OperationContract] int Add(int x, int y)
)也会起作用。而且我想它会继续这样工作,因为它对于一个单一的合同来说是完全有效的,可以进行“正常”操作,以及利用流式传输的操作,并且因为需要为每个端点设置传输模式(和不是每次操作),它也必须为“简单”操作工作。