Здравствуйте все!
Осваиваю wcf, столкнулся с проблемой. Гугление не помогло.
Имеется wcf сервис, поднимаемый в обычном managed-приложении.
Uri address = new Uri("http://localhost:8000");
service = new ServiceHost(typeof(ManagerService), address);
try
{
service.AddServiceEndpoint(typeof(ManagerService), new BasicHttpBinding(), "Manager");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
service.Description.Behaviors.Add(smb);
service.Open();
log.Debug("Запущен сервис");
}
Сервиc представлен как:
[ServiceContract]
class ManagerService
{
//...
[OperationContract]
public string GetModuleCalc(string ModuleName, string param)
{
//...
}
[OperationContract]
public void SayHello(string MyUri, string[] MyModules, Classes.ComputerParams MyComputer)
{
//...
}
[OperationContract]
public string Calc(string module, string param)
{
//...
}
}
Проблема в том, что пока сервис не выполнит один запрос, он не начинает выполнять второй и т.д. То есть запросы выполняются строго по очереди без параллельной обработки. Как сделать так, чтобы сервис мог обрабатывать запросы параллельно?
Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
Здравствуйте, GTmAster, Вы писали:
GTA>Проблема в том, что пока сервис не выполнит один запрос, он не начинает выполнять второй и т.д. То есть запросы выполняются строго по очереди без параллельной обработки. Как сделать так, чтобы сервис мог обрабатывать запросы параллельно? GTA>Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
Здравствуйте, GTmAster, Вы писали:
GTA>Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
Здравствуйте, GTmAster, Вы писали:
GTA>Проблема в том, что пока сервис не выполнит один запрос, он не начинает выполнять второй и т.д. То есть запросы выполняются строго по очереди без параллельной обработки. Как сделать так, чтобы сервис мог обрабатывать запросы параллельно? GTA>Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
По умолчанию, сервис обязан выполнять запросы параллельно. Нужно прилагать доп. усилия как раз, чтобы он перестал это делать.
Но давайте сначала поймем, каким способом Вы проверяете, параллельно ли оно работает. Ну и код методов желательно бы посмотреть...
Здравствуйте, _d_m_, Вы писали:
___>Здравствуйте, GTmAster, Вы писали:
GTA>>Проблема в том, что пока сервис не выполнит один запрос, он не начинает выполнять второй и т.д. То есть запросы выполняются строго по очереди без параллельной обработки. Как сделать так, чтобы сервис мог обрабатывать запросы параллельно? GTA>>Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
___>http://www.rsdn.ru/?article/dotnet/WCF_MultithreadClient.xml
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, GTmAster, Вы писали:
GTA>>Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
TK>На подобное http://www.rsdn.ru/forum/dotnet/4243846.1.aspx
Здравствуйте, scale_tone, Вы писали:
_>Здравствуйте, GTmAster, Вы писали:
GTA>>Проблема в том, что пока сервис не выполнит один запрос, он не начинает выполнять второй и т.д. То есть запросы выполняются строго по очереди без параллельной обработки. Как сделать так, чтобы сервис мог обрабатывать запросы параллельно? GTA>>Пробовал играться со свойствами ServiceBehavior, а именно с ConcurrencyMode и InstanceContextMode, но желаемого поведения не получил, сервис все равно выполняет запросы строго по очереди.
_>По умолчанию, сервис обязан выполнять запросы параллельно. Нужно прилагать доп. усилия как раз, чтобы он перестал это делать. _>Но давайте сначала поймем, каким способом Вы проверяете, параллельно ли оно работает. Ну и код методов желательно бы посмотреть...
Происходит запрос к одному из методов. В этом методе происходит запрос к этому же сервису (т.е. на localhost) но к другому методу. В итоге второй запрос не выполняется, вылетая по timeout.
P.S. Да, это бред подключаться снова к сервису вместо просто вызова нужного метода, просто проверка работоспособности.
Здравствуйте, GTmAster, Вы писали:
GTA>Происходит запрос к одному из методов. В этом методе происходит запрос к этому же сервису (т.е. на localhost)
Это как?! И зачем? Т.е. это что же, у Вас сервис является собственным клиентом?!
Покажите код.
GTA> но к другому методу. В итоге второй запрос не выполняется, вылетая по timeout.
И какое конкретно исключение?
GTA>P.S. Да, это бред подключаться снова к сервису вместо просто вызова нужного метода, просто проверка работоспособности.
Проверка работоспособности чего?
Чтобы проверить параллельность работы сервиса Вы вставьте Thread.Sleep() в его методы, запустите два клиента и убедитесь, что они не ждут друг друга. По умолчанию InstanceContextMode выставлен в PerSession, Вы его (судя по коду) не переопределяли, так что создадутся два экземпляра сервиса для каждого клиента, которые будут прекрасно работать.
Прична в том, что если создавать сервисы в гуёвом потоке они будут обрабатывать запросы последовательно. Скорее всего это связанно с тем, что поток является STAThread. Так как менять его тип на MTAThread не корректно (могут быть проблемы, например, с буфером обмена) то самый простой путь — создать новый поток и в неём создать и открыть сервисы.
Здравствуйте, GTmAster, Вы писали:
R>>Хост приложение не WinForms часом?
GTA>Оно самое. В этом причина странного поведения?
Да, именно из-за этого. Такое поведение by-design и оно не связано с STA/MTA моделями, а связано с тем, что сервис по умолчанию использует текущий контрекст синхронизации для обработки запросов, а поскольку винформы используют соственный контекст синхронизации, то и получается что все вызовы сервиса выполняются в потоке UI *последовательно*.
Здравствуйте, GTmAster, Вы писали:
GTA>Происходит запрос к одному из методов. В этом методе происходит запрос к этому же сервису (т.е. на localhost) но к другому методу. В итоге второй запрос не выполняется, вылетая по timeout. GTA>P.S. Да, это бред подключаться снова к сервису вместо просто вызова нужного метода, просто проверка работоспособности.
Это, как-бы нормально, если reentrant нет. А если оно есть — то уже нет многопоточности. Вывод — не чешите левой рукой правое ухо