1

私は wcf アプリケーションに取り組んでいますが、奇妙なタイムアウト動作が見られるようになりました。問題が wcf に関連しているかどうかを判断するために、実際のアプリケーションと同じ構成で foo アプリケーションを作成しました。

クライアント アプリケーション コードは次のとおりです。

public class Clients
{
    public static void Main(string[] args)
    {
        var random = new Random();
        var run = true;
        var threads = 100;

        for (int i = 0; i < threads; i++)
        {
            int delay = random.Next(1000, 1500);

            var t = new Thread(() => {
                var id = Guid.NewGuid().ToString("N").Substring(0, 10);
                var client = new Client(@"client");

                while (run)
                {
                    Console.WriteLine(@"Sending thread id " + id);
                    client.Operation(@"Thread " + id);
                    Thread.Sleep(delay);
                }
            });
            t.Start();
        }
    }
}

サーバー アプリケーション コードは、コンソールに送信されたデータのみをログに記録します。

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.Single,
    IncludeExceptionDetailInFaults = true,
    UseSynchronizationContext = false,
    ValidateMustUnderstand = false)]
public class Service : IService
{
    public void Operation(string data)
    {
        Console.WriteLine(@"Data received: {0}", data);
    }
}

これは app.config ファイルです。

<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
  <service name="Test.Service" behaviorConfiguration="throttle">
    <endpoint name="service" 
              address="net.tcp://localhost/service" 
              binding="netTcpBinding" 
              bindingConfiguration="NetTcpBinding" 
              contract="Test.IService"/>
  </service>
</services>
<client>
  <endpoint name="client"
        address="net.tcp://localhost/service"
        binding="netTcpBinding" 
        bindingConfiguration="NetTcpBinding" 
        contract="Test.IService"/>
</client>
<bindings>
  <netTcpBinding>
    <binding name="NetTcpBinding"
             portSharingEnabled="true" 
             closeTimeout="00:01:00" 
             openTimeout="00:00:30" 
             receiveTimeout="00:00:10"
             sendTimeout="00:00:10"
             transactionFlow="false" 
             transferMode="Streamed" 
             transactionProtocol="OleTransactions"
             hostNameComparisonMode="StrongWildcard" 
             maxBufferPoolSize="6553600"
             maxBufferSize="6553600"
             maxConnections="500"
             maxReceivedMessageSize="6553600">
      <readerQuotas maxDepth="128" 
                    maxStringContentLength="3276800" 
                    maxArrayLength="6553600" 
                    maxBytesPerRead="1638400"
                    maxNameTableCharCount="6553600"/>
      <security mode="None">
        <transport protectionLevel="None"/>
      </security>
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="throttle">
      <serviceThrottling maxConcurrentCalls="1000" 
                         maxConcurrentInstances="10"
                         maxConcurrentSessions="500"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>

両方のアプリケーションを実行し、クライアント アプリケーションのスレッド数が 100 であれば、すべて問題ありません。しかし、スレッド数を 300 に変更すると、次の例外が発生します。

System.ServiceModel.CommunicationException: The socket connection was aborted. 
This could be caused by an error processing your message or a receive timeout 
being exceeded by the remote host, or an underlying network resource issue. 
Local socket timeout was '00:00:10'.---> System.Net.Sockets.SocketException: 
An existing connection was forcibly closed by the remote host at
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 
offset, Int32 size, TimeSpan timeout, Boolean closing)

クアッドコア マシンでポート共有を使用しており、サービスは自己ホスト型です。

これは実際のアプリケーションと同じ問題ですが、タイムアウトが長くなります (2 分半)。InstanceContextMode.Single を使用したサービスが処理できる接続の最大数が 300 であるとは信じられません。デフォルトの ChannelInitializationTimeout 値 (5 に設定) に関する問題について読みましたが、それが問題だとは思いません (別のテストでは、すべてのスレッドに対して 1 つのクライアントを作成して開き、すべてを開始するまで 6 秒待ちました)。スレッド、結果は 10 秒後に同じ例外でした)。おそらく、私は間違った方法で何かを設定しています。

誰かが手がかりやアイデアを持っているなら、彼らは役に立ちます。前もって感謝します。

アップデート

バインディングを netTcp から basicHttpBinding に変更したところ、すべて正常に動作するようになりました (CommunicationExceptions はスローされません)。また、サービスで以前よりも速くメッセージを取得し始めましたが、basicHttpBinding でこの改善が得られた理由を知っている人はいますか?

4

0 に答える 0