我有返回大对象的服务,默认传输模式(缓冲)不适合我们的要求。
实际上,该服务已经编写好了,项目团队正在经历内存不足的异常和间歇性的性能下降。现在这需要通过一些补丁来解决,重写所有服务不是一个选项,因为项目团队即将交付。
我知道将传输模式更改为 StreamedResponse/Streamed 可能会大有帮助 + 选择 net.tcp 而不是 http 绑定(具有胖客户端的内联网应用程序)。我需要知道我是否会为所有操作合同或仅那些返回 Stream/Message 的操作合同受益。
我创建了一个小示例来检查它是否对其他返回类型(DataTable/DataSet)有任何影响,并且它似乎影响所有返回类型,包括 DataTable/DataSet。我检查了WCF HttpTransport: streamed vs buffered TransferMode并且看起来其他人也遇到了相同的行为。
这里唯一缺少的是一些具体的文档,清楚地表明它影响所有操作合同,而与返回类型无关。我需要一些参考资料,以便我可以推动我对这个 chnage 的建议。
请不要建议不要从服务中返回 DataTable/DataSet;我知道这是一种不好的做法,应该一直避免,但在这种情况下,服务已经存在,我现在不能要求他们改变一切。
更新: 我的看法是基于以下测试
我的界面
[ServiceContract]
public interface IMediaManager
{
[OperationContract]
Stream Play(int mediaId);
[OperationContract]
DataSet GetJunk();
}
我的实现
public class MediaManager : IMediaManager
{
public Stream Play(int mediaId)
{
String path = GetMedia(mediaId);
FileStream fStream = new FileStream(path, FileMode.Open, FileAccess.Read,FileShare.Read);
return fStream;
}
public DataSet GetJunk()
{
return GetLargeJunkDataSet20PlusMegs();
}
}
通过 IIS 托管 - 非 Http WAS,服务器配置文件(标签被剥离,只有相关的)
<system.serviceModel>
<services>
<service name="MediaService.MediaManager" behaviorConfiguration="MediaServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9876/MediaService/MediaManager.svc" />
</baseAddresses>
</host>
<endpoint address="" binding="customBinding"
bindingConfiguration="StreamedTcpBinding" name="MediaManagerTcp"
contract="MediaService.IMediaManager" />
<endpoint address="mexTcp" binding="mexTcpBinding" name="mexTcp"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<customBinding>
<binding name="StreamedTcpBinding" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<binaryMessageEncoding />
<tcpTransport transferMode="Streamed" portSharingEnabled="true" />
</binding>
</customBinding>
</bindings>
客户端配置文件(仅相关标签)
<binding name="MediaManagerTcp" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Streamed" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647"
***maxBufferSize="1001"*** maxConnections="10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
如果您在上面看到,maxBufferSize是 1001 字节,但实际消息将是 20+ mb。这让我觉得 Streamed 也适用于 DataSet(一切,不仅限于 Stream 和 Message)。我希望我对 maxBufferSize 的解释是正确的(它将在一个块中接收的最大大小)。我还必须补充一点,如果我切换到缓冲模式,同样的方法会失败。
我希望我的分析是有道理的,如果不清楚,请告诉我,我会再试一次?
我将再次重复我的问题,以免它丢失:)
这里唯一缺少的是一些具体的文档,清楚地表明它影响所有操作合同,而与返回类型无关。我需要一些参考/经验,以便我可以推动我对这个 chnage 的建议。
任何帮助都感激不尽!
谢谢,
一种