我有返回大对象的服务,默认transfermode(缓冲)不符合我们的要求。
实际上,服务已经编写,项目团队正在经历内存不足异常并且间歇性地降低性能。现在需要通过一些补丁修复,重新启动所有服务都不是一个选项,因为项目团队接近交付。
我理解将transfermode更改为StreamedResponse / Streamed可能会有很大帮助+选择net.tcp而不是http绑定(使用胖客户端的Intranet应用程序)。我需要知道我是否会获得所有操作合同或仅返回Stream / Message的那些操作。
我创建了一个小样本来检查它是否对其他返回类型(DataTable / DataSet)有任何影响,并且似乎它会影响所有返回类型,包括DataTable / DataSet。我检查了WCF HttpTransport: streamed vs buffered TransferMode,看起来其他人也经历过同样的行为。
这里唯一缺少的是一些具体的文档,它清楚地表明它会影响所有的操作契约,而不管返回类型如何。我需要一些参考资料,以便我可以推荐我的推荐。
请不要建议不要从服务中返回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(它将在一个块中接收的最大大小)。 我还必须补充说,如果我切换到缓冲模式,同样的方法就会失败。
我希望我的分析有道理,如果不清楚那么请告诉我,我会再试一次?
我会再次重复我的问题,以免它迷失:)
这里唯一缺少的是一些具体的文档,它清楚地表明它会影响所有的操作契约,而不管返回类型如何。我需要一些参考/经验,以便我可以推荐我的推荐。
非常感谢任何帮助!
谢谢,
A
答案 0 :(得分:1)
终于找到了相关的东西。
DataSet是IXMLSerializable的继承子,因此它是流式传输的候选者。从MSDN(Streaming Message Transfer)
中挑选了以下内容流式传输中发生的操作最多只能包含一个输入或输出参数。该参数对应于消息的整个主体,并且必须是Message,派生类型的Stream或 IXmlSerializable 实现。具有操作的返回值等同于具有输出参数。
和DataSet是 IXmlSerializable 的实现。 DataSet的definition
[SerializableAttribute]
public class DataSet : MarshalByValueComponent, IListSource,
IXmlSerializable, ISupportInitializeNotification, ISupportInitialize,ISerializable
谢谢,
A