Понимание WCF ServiceBehaviorProperty ConcurrencyMode

#c# #.net #wcf #service

#c# #.net #wcf #Обслуживание

Вопрос:

Я хотел бы понять ServiceBehavior.ConcurrencyMode свойство.

Рассмотрим следующий код на стороне службы:

 [ServiceContract]
public interface IMySercice {
   [OperationContract]
   int mycall(int a);
}
/*** HERE I WILL GENERATE Two variants of this code ***/
[ServiceBehaviour(InstanceContext = InstanceContextMode.Single)]
public class MyService : IMyService {
   // Constructors...
   // implementations of interface
   public int mycall(int a) { ... }
}
class Program {
   static void Main(string[] args) {
      MyServiceMyS = new MyService(...); /* Creating service instance */
      Uri MyUri = new Uri("http://services.mycompany.com/services/"); /* Base address for my hosted service */
      using (ServiceHost host = new ServiceHost(MyS)) { /* Defining service host, configuration file contains info regarding endpoints, not shown here for clarity */
         host.Start();
         host.Stop();
      }
   }
}
  

Теперь подумайте, что я хотел бы вызвать эту службу, пожалуйста, рассмотрите 10 компьютеров в Интернете, которые могут вызывать мою службу.
В определенный момент случается, что все эти 10 машин одновременно ДЕЛАЮТ 10 запросов на int mycall(int a) .
Я хотел бы изучить эти сценарии:

СЦЕНАРИЙ 1

 ...
/*** VARIANT 1 ***/
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContext = InstanceContextMode.Single)]
public class MyService : IMyService {
   ...
}
...
  

СЦЕНАРИЙ 2

 ...
/*** VARIANT 2 ***/
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContext = InstanceContextMode.Single)]
public class MyService : IMyService {
   ...
}
...
  

Итак, поступает 10 одновременных вызовов… что происходит в обоих случаях? Пожалуйста, скажите мне, прав я или нет:

В сценарии 1, однопоточном, эти 10 вызовов помещаются в очередь и выполняются по одному за раз. Метод моей службы (ТОТ ЖЕ ЭКЗЕМПЛЯР МОЕЙ СЛУЖБЫ) будет вызываться последовательно десять раз. В сценарии 2, многопоточный, WCF приведет к одновременному вызову моего метода обслуживания 10 потоками.

Это правда, что я сказал? Спасибо

Комментарии:

1. В обоих сценариях ваш код не будет компилироваться, потому что ServiceHost не имеет ни Start() , ни Stop() метода.

Ответ №1:

В обоих сценариях все 10 клиентов будут обслуживаться параллельно 10 различными потоками. Причина в том, что ConcurrencyMode настройка зависит от InstanceContextMode параметра. InstanceContextMode определяет, как сервер WCF engine выполняет клиентские запросы — как создается новый экземпляр службы, если поступает запрос:

  • PerCall — каждый запрос обслуживается новым экземпляром сервиса
  • PerSession — все запросы от одного экземпляра прокси обслуживаются одним и тем же экземпляром службы
  • Single — для каждого хоста одноэлементный — все запросы обслуживаются одним и тем же экземпляром службы

Таким образом, ваше описание будет правильным, если вы также используете, InstanceContextMode.Single но значение по умолчанию PerCall для привязок, не поддерживающих сеансы (базовая привязка HttpBinding, webHttpBinding, wsHttpBinding без контекста безопасности или надежного сеанса) или PerSession для привязок, поддерживающих сеансы (привязка NetTcpBinding, привязка NetNamedPipeBinding, привязка wsHttpBinding в конфигурации по умолчанию с использованием контекста безопасности).

ConcurrencyMode определяет, как может использоваться экземпляр сервиса, если несколько запросов хотят получить к нему доступ. Например, PerCall создание экземпляра с Multiple параллелизмом — это то же самое, что и Single параллелизм, потому что каждый экземпляр используется для обслуживания ровно одного запроса независимо от настройки параллелизма.

Комментарии:

1. Спасибо, Ладислав, я отредактировал код, указав Singel как InstanceContextMode, мне очень жаль, что я не сделал этого раньше… Я думаю, теперь мое описание верно, не так ли? Заранее спасибо.

2. Да, если у вас одноэлементный сервис, ваше описание должно быть правильным.

Ответ №2:

Да, использование InstanceContextMode.Single того, что вы описали, должно быть поведением, которое вы должны увидеть. Помимо 10 одновременных вызовов, вы фактически все равно получите то же поведение, потому что вы достигнете предела регулирования по умолчанию, равного 10 для MaxConcurrentSessions вашего сервиса ServiceThrottlingBehavior («сеанс», насколько это касается поведения регулирования, — это общее количество каналов, которые могут быть открыты одновременно).