サーバーアプリケーションから複数のクライアントにデータを転送するためにWCFを使用しています。実際、ほとんどのトラフィックでは、クライアントとサーバーが同じマシンで実行されているため、転送は非常に高速であると予想されます。
ただし、大きな配列 (16 ビット グレースケール イメージ) を転送する場合、データが転送されるまでに数秒かかります。16 MB のイメージの場合、約 3 ~ 5 秒かかります。
最初は、ushort
16 ビットのグレースケール イメージ データを格納するのに最も適したデータ型であるため、配列を使用していました。ただし、これは非常に遅く、16 MB で約 20 ~ 25 秒かかりました。byte
を使用してシリアル化する前にデータを配列にコピーするとBuffer.BlockCopy
、何らかの理由で 3 ~ 5 秒に短縮されます。ただし、16 MB を同じマシン上で実行されている別のアプリケーションに転送するのに 3 ~ 5 秒かかるのは、やはり私には長すぎるように思えます。
したがって、私の質問は次のとおりです。このようなシナリオのパフォーマンスをどのように改善できますか?
私はすでに Marc Gravell から protobuf-net を調査しましたが、この場合に役立つかどうかはわかりません...経験やその他の提案はありますか?
以下は、データ クラス (画像データを含む) の 1 つのソース コードです。
[DataContract(IsReference = true)]
public class ImageData
{
private ushort[] m_pixelData;
public ushort[] PixelData
{
get
{
return m_pixelData;
}
set
{
m_pixelData = value;
OnPropertyChanged("PixelData");
}
}
[DataMember]
public override byte[] FileData
{
get
{
if (this.PixelData == null)
{
return null;
}
return ListHelper.ConvertToByteArray(this.PixelData);
}
set
{
if (value == null)
{
this.PixelData = null;
return;
}
this.PixelData = ListHelper.ConvertToUshortArray(value);
}
}
}
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>
そしてクライアントのapp.config
:
<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>