Performance 提高大型阵列的WCF性能

Performance 提高大型阵列的WCF性能,performance,wcf,protobuf-net,Performance,Wcf,Protobuf Net,我们使用WCF将数据从服务器应用程序传输到多个客户端。实际上,对于大多数流量,客户端和服务器都在同一台机器上运行,因此我希望传输速度非常快 但是,在传输大型阵列(16位灰度图像)时,需要几秒钟才能传输数据。对于16 MB的图像,大约需要3-5秒 最初,我们使用的是ushort数组,因为它是存储16位灰度图像数据的最合适的数据类型。然而,这是非常缓慢的:大约20-25秒,16 MB。在使用Buffer.BlockCopy进行序列化之前,当我们将数据复制到字节数组时,由于某种原因,它会减少到3-5秒

我们使用WCF将数据从服务器应用程序传输到多个客户端。实际上,对于大多数流量,客户端和服务器都在同一台机器上运行,因此我希望传输速度非常快

但是,在传输大型阵列(16位灰度图像)时,需要几秒钟才能传输数据。对于16 MB的图像,大约需要3-5秒

最初,我们使用的是
ushort
数组,因为它是存储16位灰度图像数据的最合适的数据类型。然而,这是非常缓慢的:大约20-25秒,16 MB。在使用
Buffer.BlockCopy
进行序列化之前,当我们将数据复制到
字节
数组时,由于某种原因,它会减少到3-5秒。然而,在同一台机器上,从一个应用程序向另一个应用程序传输16MB的时间在我看来仍然太长了

因此,我的问题是:在这种情况下,我们如何提高性能?

我已经调查了Marc Gravell的protobuf网络,但我不确定它是否有助于本案。。。有什么经验或其他建议吗

以下是我们的一个数据类(包含图像数据)的源代码:

请注意,只有
FileData
属性被标记为
[DataMember]
,因此
PixelData
属性不会序列化

以下是服务器的
app.config
的相关部分:

<system.serviceModel>
    <services>
        <service name="Services.ImageDataService" behaviorConfiguration="ServicesBehavior">
            <host>
                <baseAddresses>
                    <add baseAddress="net.tcp://localhost:8008/ImageDataService" />
                </baseAddresses>
            </host>
            <endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBindingLargeFileTransfer" contract="Services.IImageDataService" />
            <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="ServicesBehavior">
                <serviceMetadata httpGetEnabled="false" />
                <serviceDebug includeExceptionDetailInFaults="false" />
                <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <netTcpBinding>
            <binding
                name="NetTcpBindingLargeFileTransfer"
                openTimeout="00:01:00" closeTimeout="00:01:00" receiveTimeout="infinite" sendTimeout="infinite"
                transactionFlow="false" transactionProtocol="OleTransactions"
                transferMode="Buffered" hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="2097152" maxBufferSize="1073741824" maxConnections="10" maxReceivedMessageSize="1073741824">
                <readerQuotas
                    maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <reliableSession ordered="true" inactivityTimeout="infinite" enabled="false" />
                <security mode="None">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
</system.serviceModel>
<system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding
                name="NetTcpBindingLargeFileTransfer"
                openTimeout="00:01:00" closeTimeout="00:01:00" receiveTimeout="infinite" sendTimeout="00:10:00"
                transactionFlow="false" transactionProtocol="OleTransactions"
                transferMode="Buffered" hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="2097152" maxBufferSize="1073741824" maxConnections="10" maxReceivedMessageSize="1073741824">
                <readerQuotas
                    maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <reliableSession ordered="true" inactivityTimeout="infinite" enabled="false" />
                <security mode="None">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
    <client>
        <endpoint
            address="net.tcp://localhost:8008/ImageDataService"
            binding="netTcpBinding"
            bindingConfiguration="NetTcpBindingLargeFileTransfer"
            contract="Services.IImageDataService"
            name="Services.IImageDataService"
            behaviorConfiguration="ServicesBehavior" />
    </client>
    <behaviors>
        <endpointBehaviors>
            <behavior name="ServicesBehavior">
                <dataContractSerializer maxItemsInObjectGraph="2147483647"></dataContractSerializer>
            </behavior>
        </endpointBehaviors>
    </behaviors>
</system.serviceModel>

在同一台计算机上尝试命名管道


尝试使用命名管道传输进行流式传输。详情请参阅本帖


在将数据发送到服务器/客户端之前,缓冲数据可能有问题。流媒体将以块的形式发送您的数据。

谢谢!这将转移时间减少到一半!我没有想到这一点,因为还有远程客户端,即在其他机器上。然而,图像数据通常不通过网络传输。因此,使用
NetNamedPipeBinding
添加另一个端点是一种可行的方法。然而,不幸的是,它甚至使它变慢了。可能数据量不够大,无法通过流式传输获得性能增益。从我在互联网上读到的内容来看,我得到的印象是,流媒体更适合于500 MB左右的大数据项。您是否也尝试过命名管道?如上所述(其他答案),命名管道将传输时间减少了一半。
<system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding
                name="NetTcpBindingLargeFileTransfer"
                openTimeout="00:01:00" closeTimeout="00:01:00" receiveTimeout="infinite" sendTimeout="00:10:00"
                transactionFlow="false" transactionProtocol="OleTransactions"
                transferMode="Buffered" hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="2097152" maxBufferSize="1073741824" maxConnections="10" maxReceivedMessageSize="1073741824">
                <readerQuotas
                    maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <reliableSession ordered="true" inactivityTimeout="infinite" enabled="false" />
                <security mode="None">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
    <client>
        <endpoint
            address="net.tcp://localhost:8008/ImageDataService"
            binding="netTcpBinding"
            bindingConfiguration="NetTcpBindingLargeFileTransfer"
            contract="Services.IImageDataService"
            name="Services.IImageDataService"
            behaviorConfiguration="ServicesBehavior" />
    </client>
    <behaviors>
        <endpointBehaviors>
            <behavior name="ServicesBehavior">
                <dataContractSerializer maxItemsInObjectGraph="2147483647"></dataContractSerializer>
            </behavior>
        </endpointBehaviors>
    </behaviors>
</system.serviceModel>