WCF Operation.Context not Thread safe? - программирование
Подтвердить что ты не робот

WCF Operation.Context not Thread safe?

Я просматриваю код службы WCF. В заголовке каждого сообщения мы вводим данные, которые служба будет использовать позже, чтобы построить строку подключения к БД. Это потому, что служба будет использоваться несколькими различными сайтами, каждая из которых имеет свою собственную БД, которую служба должна запрашивать. Мы используем расширяемость wcf. У нас есть собственный MessageInspector, который после получения запроса извлекает данные из заголовка сообщения, создает контекст (который реализует IExtension) и добавляет его в OperationContext.Current.Extensions. Перед отправкой ответа пользовательский контекст удаляется из коллекции Extencions.

Это довольно распространенный шаблон, как описано здесь:

Где хранить данные для текущего вызова WCF? Безопасен ли ThreadStatic?

и здесь:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/319cac66-66e8-4dfe-9a82-dfd289c9df1f/wcf-doesnt-have-session-storage-so-where-should-one-store-call-specific-data?forum=wcf

Все это работает отлично, пока служба получает запрос, обрабатывает его, отправляет ответ и получает следующий запрос. Но что делать, если служба получает запрос и, прежде чем сможет ответить, получает второй запрос? Для его тестирования я создал небольшое консольное приложение. Я отправляю 2 сообщения из 2 разных потоков, я заставил службу wcf ждать в течение 2 секунд, чтобы гарантировать, что второй запрос поступит до того, как первый будет завершен, и это то, что я получаю:

Идентификатор сайта: test1450; Сессия: uuid: 2caf47cf-7d46-4d72-9275-d9c037fa0e70; id = 2: Идентификатор потока: 6

Идентификатор сайта: test1450; Сессия: uuid: 2caf47cf-7d46-4d72-9275-d9c037fa0e70; id = 3: Идентификатор потока: 22

Похоже, wcf создает 2 сеанса, выполняющихся на 2 разных потоках, но идентификатор сайта одинаковый. Это не должно. Судя по этому, это выглядит как OperationContext.Current.Extensions - это коллекция, совместно используемая между потоками. Прямо сейчас я склонен думать, что мой тест ошибочен, и я что-то пропустил.

Кто-нибудь пробовал что-то подобное и выяснил, что OperationContext.Current не является потокобезопасным?

4b9b3361

Ответ 1

OperationContext.Current, как и другие аналогичные свойства, такие как HttpContext.Current, имеют потоковые аффинные (или статические) значения. Таким образом, они являются потокобезопасными в том смысле, что несколько потоков могут их читать, но разные потоки получат разные экземпляры. Их можно рассматривать как словари между конкретными потоками и экземплярами.

Итак, в этом контексте они не являются потокобезопасными.

Запросы обслуживаются пулом потоков, поэтому одновременные запросы будут иметь разные идентификаторы потоков. (до точки, где пул потоков заполнен, запросы будут помещены в режим ожидания)