【问题标题】:Wcf parallel and async call?Wcf 并行和异步调用?
【发布时间】:2011-08-02 12:58:51
【问题描述】:

我有一个 wcf 服务(解析器服务,byte[]=>string)

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]

托管在 iis (nettcpbinding) 在我的客户端,我有 100 万多字节 [] 像这个 List(1000000) 并且我应该调用 wcf 服务的方法作为并行来解析这个列表。

我是这样使用的,但是在解析 500000-700000 条消息后我遇到了瓶颈(wcf 服务没有响应我)。我在哪里执行错误?如果我实现此http://blogs.msdn.com/b/rjacobs/archive/2011/06/30/how-to-implement-a-wcf-asynchronous-service-operation-with-task-lt-t-gt.aspx 方法(Parallel.Foreach 中的客户端与下一行相同)是否解决了我的问题

Service1 client =new Service1();
Parallel.Foeach(list,byteArray=>{
  var result = client.Parse(byteArray);
  string keyHash = string.combine(byteArray[0],byteArray[1],byteArray[3])
  WriteDiffFile(keyHash,result); // maybe call in different task 
  WriteSameFile(result); // need lock for write to same file
});

我的 wcf 主机配置:

<system.serviceModel>
    <diagnostics etwProviderId="9a712944-02ea-425a-bbd3-567a943b85df">
      <endToEndTracing propagateActivity="false" messageFlowTracing="false" />
    </diagnostics>
    <services>
      <service name="Pln3G.Services.EventParserService" behaviorConfiguration="Pln3G.WebServices.EventParserServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8001/pln3g/EventParserService/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcp_Unsecured" contract="Pln3G.Domain.Contracts.Service.IEventParserService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="tcp_Unsecured" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" portSharingEnabled="false" transactionFlow="false" listenBacklog="2147483647" closeTimeout="00:01:00" openTimeout="00:10:00" receiveTimeout="00:20:00" sendTimeout="00:10:00">
          <readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None"></security>
        </binding>
      </netTcpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="Pln3G.WebServices.EventParserServiceBehavior">
          <etwTracking profileName="ErrorsOnly Tracking Profile" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
          <!--1. MaxConcurrentSessions: default is 100 * ProcessorCount
                2. MaxConcurrentCalls: default is 16 * ProcessorCount
                3. MaxConcurrentInstances: default is the total of MaxConcurrentSessions and MaxConcurrentCalls -->
          <serviceThrottling maxConcurrentCalls="32" maxConcurrentSessions="200" maxConcurrentInstances="232" />
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
        <behavior name="">
          <etwTracking profileName="HealthMonitoring Tracking Profile" />
          <serviceThrottling maxConcurrentCalls="32" maxConcurrentSessions="200" maxConcurrentInstances="232" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

我的 wcf 客户端配置:

<system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IEventParserService" closeTimeout="00:01:00" openTimeout="00:10:00" receiveTimeout="00:20:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <!--<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />-->
          <security mode="None">
            <transport clientCredentialType="None" protectionLevel="None" />
            <message clientCredentialType="None" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://192.168.1.66:8001/pln3g/EventParserService.svc" behaviorConfiguration="ServiceViewEventBehavior"
          binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IEventParserService"
          contract="EventParserServiceReference.IEventParserService" name="NetTcpBinding_IEventParserService" />
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ServiceViewEventBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

【问题讨论】:

  • 挂起您的服务需要多长时间(大约)?
  • 它睡了 5 分钟以上,但没有回应我
  • 尝试检查perf mon 的数据,看看它是否能给你提供线索

标签: c# wcf asynchronous call parallel-processing


【解决方案1】:

我建议你使用PerCall InstanceContextMode,在这种模式下,它为不同的调用创建不同的实例,并在不同的线程中调用它们;如果您使用 PerSession,它只会为您的会话创建一个实例,根据您的客户端代码,它只会创建实例并为您的请求提供服务。

【讨论】:

  • 在 PerCall 案例中;我需要在 Parallel.Foreach 循环中从 Service1 客户端创建新实例吗?
猜你喜欢
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
相关资源
最近更新 更多