Подтвердить что ты не робот

Помеченные поля С# ThreadStaticAttribute автоматически освобождаются, когда поток умирает?

Я обнаружил "ThreadStaticAttribute", и у меня есть много вопросов об этом: все мои предыдущие зависящие от потока статические данные были реализованы как статический словарь, который TKey является Thread, и когда я хотел получить к нему доступ, я использовал Thread.CurrentThread и это работает. Но для этого требуется mantainance, потому что, если поток умирает, я должен удалить соответствующую запись из словаря. И мне также нужно учитывать безопасность потоков и многое другое.

Используя ThreadStaticAttribute, все эти вопросы, похоже, решаются, но я должен быть уверен в этом. Мои вопросы: мне нужно удалить захват экземпляра пометкой "ThreadStaticAttribute", каким-то образом, до того, как поток погибнет? Где находится информация об этом поле? Это в экземпляре объекта Thread или что-то в этом роде, так что, когда он больше не используется, сборщик мусора автоматически отбрасывает его? Существуют ли штрафы за производительность? Какие? Это быстрее, чем использование коллекции Keyed, как я делал?

Пожалуйста, мне нужно уточнить, как работает ThreadStaticAttribute.

Спасибо.

4b9b3361

Ответ 1

Нет, вам не нужно удалять экземпляры справки о значениях в поле, помеченном ThreadStatic. Сборщик мусора автоматически подберет их, когда и поток, и объект больше не будут доступны корневыми объектами.

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

Что касается того, где это поле фактически хранится, оно несколько не имеет значения. Все, что вам нужно беспокоиться, это то, что он будет вести себя как любой другой объект в .Net. Единственными двумя отличиями в поведении являются

  • Поле будет ссылаться на другое значение для каждого потока доступа.
  • Инициализатор для поля будет запускаться только один раз (на практике это плохая идея иметь).

Ответ 2

Пометка статической переменной-члена как [ThreadStatic] сообщает компилятору о ее распределении в области памяти потоков (например, где выделен стек потока), а не в глобальной области памяти. Таким образом, каждый поток будет иметь свою собственную копию (которая, как гарантируется, будет инициализирована значением по умолчанию для этого типа, например: null, 0, false и т.д., Не используйте инициализаторы в строке, поскольку они будут инициализировать только один поток).

Итак, когда поток уходит, так же как и область памяти, освобождая ссылку. Конечно, если это требует более быстрого удаления (открытые потоки файлов и т.д.) Вместо того, чтобы ждать фоновой сборки мусора, вам может потребоваться убедиться, что вы сделаете это до выхода потока.

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

Исправление: С тех пор я слышал, что доступ к переменным ThreadStatic несколько медленнее, чем доступ к обычным статическим переменным. Я не уверен, что даже на самом деле быстрее, чем доступ к коллекции с ключом, но он предотвращает проблемы с сиротами (это был ваш вопрос) и нуждался в блокировке для обеспечения безопасности потоков, что усложняло бы подход, основанный на сборке.