Current
является собственностью, а не поле, так что это статический метод на самом деле.
Этот метод может возвращать разные экземпляры для разных потоков, и это действительно так.
Если вы разрабатываете многопоточное веб-приложение, имейте в виду несколько вещей.
Не использовать ThreadStaticAttribute
. Он работает в Windows и консольных приложениях, но может не работать в веб-приложениях, поскольку один запрос может обрабатываться разными потоками, если вы используете async
, await
и Task<T>
.
Использовать HttpContext.Current.Items
вместо ThreadStaticAttribute
. Эти Items
являются «статическими» в каждом HttpContext
.
Использование SynchronizationContext если вам нужны важные параметры HttpContext
(региональные настройки, пользователь вошедший, и свой собственный HttpContext.Items
) после асинхронных вызовов (если вы не используете await
).
Причина, по которой вы должны быть осторожны, это пул потоков. Вполне возможно, что ваш асинхронный метод запускается в первом потоке, продолжается через секунду и заканчивается на третьем. Поскольку каждый поток имеет свою собственную копию статического поля потока, вы можете получить непредсказуемые различные значения поля в разных местах вашего метода. SynchronizationContext
позволяет вам вернуться к исходному потоку с правильными значениями региональных настроек, HttpContext.Items
и т. Д. Оператор await
работает для вас, поэтому вам не нужно заботиться о контексте, если вы используете await
(благодаря @StephenCleary для коррекции).
Теперь для потоков-статических полей. Когда ASP.NET получает HTTP-запрос, он создает новый экземпляр HttpContext
с пустой коллекцией HttpContext.Items
. В то же время поля ThreadStatic
инициализируются уже предыдущим HTTP-запросом. Поэтому f.e. a Singleton
класс, основанный на потоковом поле, может работать неправильно.Это важно как в синхронных, так и в асинхронных методах веб-приложения.
Нет необходимости явно использовать 'SynchronizationContext'; 'await' будет делать это автоматически по умолчанию. –
Спасибо. Похоже, я немного параноик. Я исправлю свой ответ. –
@MarkShevchenko Но я не могу найти какой-либо атрибут ThreadStatic, используемый внутри файла HttpContext.cs. Где это на самом деле используется ?! – rejnev