Служба WCF использует несколько потоков для обработки входящих запросов? - PullRequest
5 голосов
/ 17 февраля 2012

Как я могу убедиться, что служба WCF использует потоки из ThreadPool для обработки входящих сообщений?

На данный момент простой вызов метода типа 'return null;' занимает около 45 секунд, пока другие запросы обрабатываются

Вот как я прокомментировал свой класс обслуживания:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
    public partial class MyService : IMyService {
...
}

Но когда я наблюдаю за процессом в диспетчере задач, кажется, что он использует постоянное количество потоков. Даже под нагрузкой.


public ActionResult SelectDatabase(string param)
        {
            if (!String.IsNullOrEmpty(param))
            {
            try
            {
                MyServicece svc = new MyService();
                Database[] dbsArray = svc.GetDatabases(param);
                if (depsArray != null)
                    ViewData["depsArray"] = depsArray;

                return View();
            }
            catch (Exception exc)
            {
                // log here                
                return ActionUnavailable();
            }
        }

Вот мое служебное поведение:

<?xml version="1.0"?>
<configuration>
  <runtime>

  </runtime>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="100" />
    </connectionManagement>
  </system.net>
  <system.serviceModel>
    <diagnostics performanceCounters="Default" />
    <bindings>      
      <netTcpBinding>
        <binding sendTimeout="00:02:00" receiveTimeout="00:02:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
          <security mode="None">           
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <behaviors>
      <endpointBehaviors>
        <behavior name="CrossDomainServiceBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="MyService.MyServiceBehavior">
          <serviceThrottling maxConcurrentCalls="100"   maxConcurrentInstances="100" maxConcurrentSessions="100" />
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyService">
        <endpoint address="MyService" binding="netTcpBinding" contract="AService.IAServ"  isSystemEndpoint="false" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
      <service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyServiceAdmin">
        <endpoint address="MyServiceAdmin" binding="netTcpBinding" contract="MyService.IMyServiceAdmin"  isSystemEndpoint="false" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />        
      </service>
    </services>
  </system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

Вот как я создаю экземпляр службы:

ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(String.Format("net.tcp://{0}/", _bindAddress)));
            myserviceHost.Open();
            Console.WriteLine(myserviceHost.BaseAddresses[0]);

1 Ответ

5 голосов
/ 17 февраля 2012

InstanceContextMode и ConcurrencyMode являются отдельными концепциями, но имеют уровень взаимодействия - Я писал об этом в некоторой глубине некоторое время назад

Вызовы WCF обрабатываются в потоках пула ввода-вывода. Предполагая, что вы не сделали что-то вроде ConcurrencyMode.Single, InstanceContextMode.Single, которое будет сериализовать каждый вызов в службу, диспетчер потоков пула попытается сбалансировать количество потоков и скорость работы.

Если количество одновременных запросов может обслуживаться 5 потоками, то это то, сколько он будет использовать. Вы можете видеть, что пул потоков может идти в ногу со скоростью работы с количеством потоков, которые вы видите. Вы можете успешно использовать больше потоков, чем ядер с эффектом, потому что, если потоки не связаны исключительно с процессором, ОС может увеличить пропускную способность, переключая потоки на процессор, когда ранее запущенный поток запускает ввод-вывод. Если ЦП полностью загружен, то эвристика менеджера пула потоков заставит не добавлять новые потоки в пул потоков

Однако есть еще пара потенциальных проблем:

  1. Привязки на основе сеанса могут блокироваться на стороне клиента, когда существует несколько одновременных исходящих запросов через один и тот же прокси-сервер. Вы не говорите, как вы генерируете несколько запросов, так что это может быть проблемой;
  2. Вы также можете увидеть, как срабатывает регулирование, поскольку до .NET 4 максимальное число одновременных запросов по умолчанию составляло 16, а число одновременных сеансов по умолчанию равнялось 10. Эти значения были повышены в .NET 4, но вы этого не делаете скажи какую версию .NET ты используешь
...