2012-02-17 3 views
5

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

В настоящий момент простой вызов метода, например '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]); 
+3

InstanceContextMode = SIngle означает: у вас есть ** singleton ** - всего один экземпляр службы. Не очень масштабируемый! ConcurrencyMode = Множество означает, что singleton может обслуживать сразу несколько запросов на обслуживание, но это также означает, что код реализации вашей службы ** должен быть 100% потокобезопасным - не простая задача! Я бы рекомендовал использовать 'InstanceContextMode.PerCall' и' ConcurrencyMode.Single' - таким образом, каждый входящий запрос WCF получает свой собственный экземпляр класса сервиса для обработки запроса. Рабочая среда WCF может обрабатывать несколько одновременных запросов, ваш код легко писать. –

+0

Возможный дубликат: http: // stackoverflow.com/questions/1609703/wcf-concurrencymode-multiple-connection-best-practices-and-caching –

+1

Иногда InstanceContextMode = Single - это нормально - например, когда API не имеет состояния и просто переадресовывает вызов. Не нужно иметь более одного экземпляра службы, когда-либо созданной. Например, вызовы методов, которые возвращают такие вещи, как длины очереди, или отправляют данные в очередь обработки ... И написание 100% -ного потока безопасного кода является стандартным поведением для некоторых из нас - не для всех это сценарий kiddie. – TomTom

ответ

5

InstanceContextMode и ConcurrencyMode отдельные понятия, но которые имеют уровень взаимодействия - I blogged about this в некоторой глубине a назад

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

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

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

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

Я нахожусь на .NET4. На веб-сайте ASP.NET я создаю новый прокси каждый раз, когда я должен запрашивать что-то из службы. Похоже, мы идем по правильному пути, и это может быть проблемой. – kseen

+0

См. Обновление моего сообщения. – kseen

+0

Вы звоните близко к прокси? –

Смежные вопросы