У меня есть требование к моему приложению, которое, я думаю, можно удовлетворить, используя локальное хранилище потоков, но мне интересно, является ли это одной из тех вещей, которых лучше избегать.
Я прочитал несколько статей на эту тему:
http://www.dotnetcoders.com/web/Articles/ShowArticle.aspx?article=58
http://msdn.microsoft.com/en-us/library/system.threadstaticattribute(vs.80).aspx
Я знаю, что как его использует, мне просто интересно, использую ли я его должен.
Есть какие-нибудь советы, о которых нужно знать?
[Редактировать]
Вот пример использования:
Я направляю весь доступ к данным с помощью нескольких методов, которые ведут много журналов по каждому запросу. Одна вещь, которую я регистрирую, - это полный дамп текста команды с заполненными командами, так что я могу просто скопировать и вставить из моих журналов трассировки прямо в Sql Management Studio.
Поднявшись в global.asax в своих веб-приложениях, я отправляю электронное письмо администраторам с максимально возможной информацией, когда получаю необработанное исключение. Я хочу поместить этот текст дампа команды sql в это электронное письмо, когда я получу SqlException, что сэкономит мне время на копание в журналах трассировки, когда страница взрывается из-за запроса.
Я не хочу изменять сигнатуры методов моих классов доступа к данным, чтобы я мог передать некоторую ссылку на всем протяжении стека, просто чтобы получить ее, когда я получу исключение. Я подумал, может быть, TLS было бы хорошим местом для размещения чего-то вроде "lastsqlcommand", но это не выглядело как жизнеспособное решение.





Проблема для приложений asp.net: обработка одного запроса может переключать потоки, а именно, если в одном сеансе есть параллельные запросы. Из-за этого все, что вы поместили в TLS до события HttpApplication.PostRequireRequestState, может не быть там позже, потому что вы находитесь в другом потоке.
[Редактировать автор вопроса]
В моем конкретном случае использования я добавил пару «ключ-значение» в словарь SqlException.Data, который затем извлекаю, когда регистрирую подробности исключения. Это дает мне функциональность, для которой я надеялся использовать локальное хранилище потоков.
Это именно то, что я искал. Я подозревал, что в этом случае это может быть ненадежно. Спасибо.
Это старый ответ, но чтобы немного уточнить: ASP.NET переключает потоки только в очень специфических сценариях. Самым большим из них является использование асинхронных методов ввода-вывода - см., Например, Лотка и Гатри обсуждают: lhotka.net/WeBlog/…
Локальное хранилище потоков - это быстрый способ исправить библиотеку, которая была разработана до потоков и использует множество глобальных переменных и статики. Это способ, которым стандартная библиотека C была сделана поточно-ориентированной, не меняя при этом ее интерфейс (внутри многие функции используют статические буферы).
В общем, для этой цели это вроде как хорошо. Если вам нужно иметь глобальные данные в многопоточной среде, то локальное хранилище потоков - хороший вариант. Распространенная причина заключается в том, что вы вызываете стороннюю функцию, которая вызывает вас обратно в том же стековом фрейме, но не дает вам возможности передать дополнительную информацию - это часто случается, когда вы пытаетесь обернуть старые библиотеки C в .СЕТЬ.
Взгляните на новый класс .net 4 ThreadLocal <T> с примером, подробнее здесь.
Я всегда избегал локального хранилища потоков и нашел другой способ сделать то же самое. Я всегда думал, что локальное хранилище потока, вероятно, медленнее, чем прямой доступ (не уверен, правильно это или нет). Мне было бы любопытно, что думают и другие.