.net WCF服务并发问题和超时

.net WCF服务并发问题和超时,.net,wcf,wcf-binding,wcf-client,.net,Wcf,Wcf Binding,Wcf Client,我有一个WCF服务,它从一个应用程序接收消息,并向其他连接的客户端应用程序发送通知 在我的第一个测试场景中,一个客户端应用程序每秒向服务发送大量消息,而另外两个应用程序则从服务接收这些消息。在这次测试中,我的服务非常好 但是,如果我添加另一个发送消息的客户端应用程序(两个应用程序向服务发送消息),应用程序将崩溃并抛出超时异常(大多数情况下是SendTimeOut) 第二个测试中每秒的消息量低于第一个测试,因为我在请求之间使用Thread.Sleep(),所以我认为问题在于发送请求的应用程序的数量

我有一个WCF服务,它从一个应用程序接收消息,并向其他连接的客户端应用程序发送通知

在我的第一个测试场景中,一个客户端应用程序每秒向服务发送大量消息,而另外两个应用程序则从服务接收这些消息。在这次测试中,我的服务非常好

但是,如果我添加另一个发送消息的客户端应用程序(两个应用程序向服务发送消息),应用程序将崩溃并抛出超时异常(大多数情况下是SendTimeOut)

第二个测试中每秒的消息量低于第一个测试,因为我在请求之间使用Thread.Sleep(),所以我认为问题在于发送请求的应用程序的数量多于请求的数量,但我不确定

你知道为什么会发生这些问题吗

我的服务和客户端应用程序编码如下:

服务合同:

[ServiceContract(CallbackContract = typeof(ICacheCommunicatorServiceCallback), SessionMode = SessionMode.Required)]
public interface ICacheCommunicatorService
{
    [OperationContract(IsInitiating = true, IsOneWay = true)]
    void Connect(string appName, string machineName);

    [OperationContract(IsTerminating = true, IsOneWay = true)]
    void DisconnectClient(ICacheCommunicatorServiceCallback callback);

    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginSendNotification(Notification notification, AsyncCallback callback, object state);
    void EndSendNotification(IAsyncResult result);
}
请求方法代码:

public IAsyncResult BeginSendNotification(Notification notification, AsyncCallback callback, object state)
    {
        try
        {
            ICacheCommunicatorServiceCallback current = CurrentCallback;

            ClientInfo sender = clients[current];

            foreach (ICacheCommunicatorServiceCallback client in clients.Keys)
            {                   
                if (client != current)
                {                       
                    if (((ICommunicationObject)client).State == CommunicationState.Opened)
                    {
                        client.ReceiveNotification(notification);
                    }
                    else
                    {
                        DisconnectClient(client);
                    }
                }
            }
        }
        catch (Exception e)
        {
            Log(e);
        }
        return new CompletedAsyncResult();
    }

    public void EndSendNotification(IAsyncResult asyncResult) { }
服务配置:

 <system.serviceModel>
<services>
  <service behaviorConfiguration="DefaultBehavior" name="CacheCommunicator.CacheCommunicatorService">
    <endpoint address="tcp" binding="netTcpBinding" bindingConfiguration="tcpBindingConfiguration"
      name="TcpEndpoint" contract="CacheCommunicator.ICacheCommunicatorService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" name="MexEndpoint" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8733/CacheCommunicator/" />
        <add baseAddress="http://localhost:8732/CacheCommunicator/" />
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <netTcpBinding>
    <binding name="tcpBindingConfiguration"
             closeTimeout="00:00:05"
             maxBufferSize="1048576"
             maxBufferPoolSize="1048576"
             maxConnections="10"
             maxReceivedMessageSize="1048576"
             openTimeout="00:00:05"
             receiveTimeout="01:00:00"
             sendTimeout="01:00:00"
             transferMode="Buffered">
      <readerQuotas maxArrayLength="1048576" maxBytesPerRead="1048576" maxStringContentLength="1048576"/>
      <reliableSession enabled="false" inactivityTimeout="01:00:00"/>
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="DefaultBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
  </serviceBehaviors>
</behaviors>
 <system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="TcpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
      <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
        <message clientCredentialType="Windows"/>
      </security>
    </binding>
  </netTcpBinding>
</bindings>
客户端应用程序配置:

 <system.serviceModel>
<services>
  <service behaviorConfiguration="DefaultBehavior" name="CacheCommunicator.CacheCommunicatorService">
    <endpoint address="tcp" binding="netTcpBinding" bindingConfiguration="tcpBindingConfiguration"
      name="TcpEndpoint" contract="CacheCommunicator.ICacheCommunicatorService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexTcpBinding" name="MexEndpoint" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8733/CacheCommunicator/" />
        <add baseAddress="http://localhost:8732/CacheCommunicator/" />
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <netTcpBinding>
    <binding name="tcpBindingConfiguration"
             closeTimeout="00:00:05"
             maxBufferSize="1048576"
             maxBufferPoolSize="1048576"
             maxConnections="10"
             maxReceivedMessageSize="1048576"
             openTimeout="00:00:05"
             receiveTimeout="01:00:00"
             sendTimeout="01:00:00"
             transferMode="Buffered">
      <readerQuotas maxArrayLength="1048576" maxBytesPerRead="1048576" maxStringContentLength="1048576"/>
      <reliableSession enabled="false" inactivityTimeout="01:00:00"/>
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="DefaultBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
  </serviceBehaviors>
</behaviors>
 <system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="TcpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
      <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
        <message clientCredentialType="Windows"/>
      </security>
    </binding>
  </netTcpBinding>
</bindings>

尝试为服务器WCF服务明确设置限制设置:


顺便问一下,WCF服务使用哪个ConcurrencyMode/InstanceMode

建议阅读:


确保每次调用后都在客户端代理上调用.Close()。您可以通过代理的一个实例进行多个调用,但在完成客户端调用后,始终可以使用.Close()。

谢谢您的回答。WCF服务使用InstanceMode.Single和ConcurrencyMode.Multiple。