1

サブスクライブしたクライアントにデータを送信する WCF サービスがあります。シーケンシャル ループを使用すると、ループ内に 3 つのループがあるため、プロセスが非常に遅くなります。

for (int x = 0 ; x <= MasterTables.count - 1 ;x ++)
{
    for (int y = 0; y <= MasterData[x].count ; y++)
    {
        foreach (SubList subscriber in subscribers.ToList())
        {
            SendDatatoSubscriber();
        }
    }
}

その代わりに、シーケンシャル ループをパラレル ループに変更しました。これにより、はるかに高速になりましたが、サーバーが多数のコールバックを単一のサブスクライバーに同時に発行しているため、伝送チャネルがタイムアウトするという欠点がありました。

SendDatatoSubscriber() イベントは同期呼び出しです。この結果に依存するイベントが他にもあるため、クライアントがオブジェクトを受信したことを確認し、特定のメッセージをサーバーに返す必要があるためです。

私のWeb構成とクライアント構成は次のとおりです。

サービス構成:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <authentication mode="None"/>
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpSecure" closeTimeout="23:00:00" openTimeout="23:00:00" receiveTimeout="23:00:00" sendTimeout="23:00:00" transactionFlow="false" transferMode="Buffered" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2000" maxReceivedMessageSize="2147483647" portSharingEnabled="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <reliableSession inactivityTimeout="23:00:00" enabled="false"/>
          <security mode="Message">
            <transport clientCredentialType="None">
              <extendedProtectionPolicy policyEnforcement="Never"/>
            </transport>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="service.ClientBehavior" name=" service.DTSClient">
        <endpoint address="" behaviorConfiguration="WcfDts.DTSClientEndpointBehavior" binding="netTcpBinding" bindingConfiguration="NetTcpSecure" name="ClientNetTcp" contract="WcfDts.IDTSClient"/>
        <endpoint address="mex" binding="mexHttpBinding" behaviorConfiguration="WcfDts.DTSClientEndpointBehavior" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://127.0.0.1:8000/WcfDts/Services"/>
          </baseAddresses>
          <timeouts closeTimeout="23:00:00"/>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name=" service.DTSClientEndpointBehavior">
          <wsdlExtensions location="http://127.0.0.1/ service /Services/DTSClient.svc" singleFile="True"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name=" service.ClientBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType=" service.CustomUserNameValidator, service "/>
            <serviceCertificate findValue="CertName" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
            <clientCertificate>
              <certificate findValue=" CertName " storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
            </clientCertificate>
          </serviceCredentials>
          <serviceThrottling maxConcurrentCalls="2000" maxConcurrentInstances="2000" maxConcurrentSessions="2000"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="wsdlExtensions" type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

クライアント構成:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="ClientNetTcp" closeTimeout="23:59:59" openTimeout="23:59:59" receiveTimeout="23:59:59" sendTimeout="23:59:59" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="100000" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="100000" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <reliableSession ordered="true" inactivityTimeout="23:59:59" enabled="false"/>
          <security mode="Message">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://BaseAdress:Port/Services/Service.svc" binding="netTcpBinding" bindingConfiguration="ClientNetTcp" contract="Sub.IClient" name="ClientNetTcp">
        <identity>
          <dns value="CertName"/>
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

だから私の質問は:

  1. タイムアウトの状況を抑えるために構成を変更する必要がありますか
  2. または、サブスクライバーがコールバックを並行して受信するようにするにはどうすればよいですか?
4

1 に答える 1

0

以下のように SendData を作成することを検討する必要があります。列は並列、行は順次です。

サブスクライバー 1 | サブスクライバー 2 | サブスクライバー 3 | ....

データ送信 1 | データ送信 1 | データ送信 1

データ送信 2 | データ送信 2 | データ送信 2

データ送信 3 | データ送信 3 | データ送信 3

.....

つまり、異なるサブスクライバーのデータを並行して送信するための呼び出しを行うことができます。したがって、一度に複数のサブスクライバーにデータを送信していますが、同時に個々のサブスクライバーに対しては、タイムアウトにならないように順次送信する必要があります。

于 2013-02-11T12:53:11.723 に答える