Могут ли два параллельных запроса WCF обрабатываться одним потоком, когда ConcurrencyMode = Multiple
У меня есть служба WCF с ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple). Я хочу использовать переменную ThreadStatic для среза данных.
Я начинаю беспокоиться о том, возможно ли, чтобы два параллельных запроса на один и тот же или другой объект OperationContracts обрабатывались одним и тем же потоком на стороне сервера, потому что, если это произойдет, моя переменная ThreadStatic будет переопределена (т.е. что-то вроде изменения потока между HttpHandlers и HttpModules в ASP.NET.)
Я сделал сервис с шипами с тем же ServiceBehaviour и maxConcurrentCalls="2". После этого клиент wcf позвонил в службу с 50 параллельными запросами, и мое беспокойство не возникло. Однако это не 100% доказательство.
Заранее спасибо!
3 ответа
Независимо от режима ConcurrencyMode, ThreadStatic
значение будет сохраняться, когда ваш запрос завершится и поток вернется в пул потоков. Этот же поток может быть повторно использован для последующего запроса, который, следовательно, сможет увидеть ваш ThreadStatic
значение.
Очевидно, что это не будет верно для двух одновременных запросов, потому что по определению они будут выполняться в разных потоках.
Из комментариев:
Также по определению MSDN говорит: "Экземпляр службы многопоточный. Никаких гарантий синхронизации не сделано. Поскольку другие потоки могут изменить ваш сервисный объект в любое время, вы должны всегда выполнять синхронизацию и согласованность состояний ". Так что это не так очевидно:)
Это означает, что один экземпляр вашего класса обслуживания может быть доступен одновременно по нескольким запросам. Таким образом, вам потребуется обработать синхронизацию для любого доступа к членам экземпляра класса обслуживания.
тем не мение ThreadStatic
члены по определению используются только одним потоком (и, следовательно, одним запросом) за раз, поэтому не требуется синхронизация.
Прямой ответ на ваш вопрос - ответ Джо.
Однако в комментариях вы упоминаете, что используете шаблон внешнего дизайна. Этот шаблон уже реализован в WCF как OperationContext и специально разработан для расширения. Я настоятельно рекомендую использовать OperationContext поверх любого пользовательского хранилища потоков.
См. Где хранить данные для текущего вызова WCF? ThreadStatic безопасно?
Я хотел бы добавить ответ Джо здесь, потому что я бы порекомендовал вам использовать какую-то корреляцию для ваших запросов, если вам нужно сохранить состояние. Модель нарезания резьбы станет очень извилистой и ненадежной в производстве.
Кроме того, теперь представьте, что у вас есть два сервера IIS, на которых размещается эта служба, и аппаратный или программный балансировщик нагрузки, обращенный вперед, чтобы вы могли использовать его. Чтобы обеспечить правильное состояние, вам понадобится корреляция, потому что вы никогда не знаете, на каком сервере будет запущена служба. В посте ниже я описал упрощенную версию того, как это может работать. Следует иметь в виду, что SessionState
необходимо хранить в общем месте для всех экземпляров службы, например, для сервера AppFabric Cache.