#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
(«сеанс», насколько это касается поведения регулирования, — это общее количество каналов, которые могут быть открыты одновременно).