Использование пула потоков в реализации сервиса .NET REST - PullRequest
7 голосов
/ 05 января 2011

Я реализую свой первый REST-сервис в .NET 4 и столкнулся с чем-то неожиданным.Кажется, что я не понимаю подчеркивающую работу ServiceModel от Microsoft, но не смог найти ответ традиционным способом.

Чтобы реализовать свой веб-сервис, я следовал инструкциям в этом руководстве: http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx

Сервис работает.Что меня удивило, так это то, что Application_BeginRequest и Application_EndRequest в Global.asax вызываются разными потоками.Глядя на трассировку стека, кажется, что эти потоки основаны на каком-то пуле потоков.

Без проведения некоторого рефакторинга это проблема для нас, поскольку мы всегда предполагали, что один запрос всегда будет выполняться в одном потоке, из-за чего мы хранили некоторые переменные, хранящиеся в локальном хранилище потока.Переменные инициализируются в Application_BeginRequest и освобождаются в Application_EndRequest.Похоже, что с ServiceModel это неправильный подход.

Мои вопросы:

  1. Могу ли я сделать какие-либо предположения о том, какие потоки запускают мой код, когда я использую ServiceModel?
  2. Есть ли способ ограничить выполнение одним потоком?Будет ли это плохо по какой-либо причине?
  3. Как правильно хранить переменную на время запроса при использовании ServiceModel?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 12 мая 2011

Одна вещь, которую я бы предложил, - рассмотреть возможность использования перехватчиков WCF, а не методов Application_BeginRequest и Application_EndRequest.Четыре примера, вот четыре из более полезных хуков:

AfterReceiveRequest -> BeforeCall -> Вызов метода -> AfterCall -> BeforeSendReply

Там хуки довольно мощные.Вы проверяете параметры перед вызовом вашего метода (централизуйте некоторые записи в одном месте) и делаете все другие полезные вещи.Это не единственные доступные хуки, есть и другие, которые я использую.Например, GetInstance позволяет мне переопределить создание объекта класса обслуживания (так что вы можете использовать структуры внедрения зависимостей и т. Д.).

Когда я использую режим параллелизма для каждого вызова, эти ловушки плюс сам вызов метода ВСЕ получаютв той же теме.Надеюсь это поможет.Я могу предоставить ссылки на реализацию этих хуков, если хотите.

Cheers

0 голосов
/ 05 января 2011

Возможно, вы захотите взглянуть на атрибут [ServiceBehavior] в реализации службы, поскольку он поддерживает аргументы для управления количеством создаваемых экземпляров и используемой моделью потоков.

http://msdn.microsoft.com/en-us/library/cc681240.aspx

Когда у вас есть

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

ваша служба будет работать как одиночная, но с несколькими потоками - до порогового значения, установленного в конфигурации WCF, - вызывая ваши методы. Чтобы заставить его работать только в одном потоке и тем самым сериализовать входящих запросов, установите ConcurrencyMode.Single.

В качестве альтернативы, вы можете запустить новый экземпляр вашего сервиса для каждого звонка:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                 ConcurrencyMode = ConcurrencyMode.Single)] 
public class MyService : IMyService

Экземпляр будет иметь доступ только к одному потоку. Фактически, когда у вас есть InstanceContextMode.PerCall, ConcurrencyMode игнорируется, потому что он всегда «Single», и каждый экземпляр выполняется в своем собственном потоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...