Поделиться через


Локальное хранилище потока: статические поля потока и области данных

Обновлен: Ноябрь 2007

Для хранения данных, уникально относящихся к потоку и домену приложения, служит управляемое локальное хранилище потока (TLS). Платформа .NET Framework предоставляет два метода для использования локального хранилища потока: статические поля потока и области данных.

  • Если фактические требования к приложению можно определить во время компиляции, следует использовать статические поля потока (поля Shared для потока в Visual Basic). Статические поля потока обеспечивают самую высокую производительность. Они также дают преимущества проверки типов во время компиляции.

  • Если фактические требования могут определяться только во время выполнения, следует использовать области данных. Области данных работают медленнее и не столь удобны в применении по сравнению со статическими полями потока, а данные хранятся с типом Object, поэтому перед использованием их необходимо привести к правильному типу.

В неуправляемом коде C++ функция TlsAlloc используется для динамического выделения областей, а функция __declspec(thread) объявляет, что в хранилище потока необходимо выделить переменную. Статические поля потока и области данных предоставляют управляемую версию этих функций.

Уникальность данных в управляемом локальном хранилище потока

При использовании статических полей потока или областей данных управляемое локальное хранилище потока будет содержать данные, уникальные относительно сочетания потока и домена приложения.

  • Один поток не может изменять данные из другого потока в пределах домена приложений, даже если оба потока используют одно поле или одну область данных.

  • Если поток получает доступ к одному потоку или области данных из нескольких доменов приложений, в каждом домене приложения хранится отдельное значение.

Например, если поток устанавливает значение статического поля потока, входит в другой домен приложения и запрашивает значение этого поля, то значение, возвращаемое во втором домене приложения, отличается от значения в первом домене. Задание нового значения для поля во втором домене приложения не затрагивает значение поля в первом домене.

Аналогично, когда поток получает доступ к области данных, имеющей одинаковое имя в двух доменах приложения, данные в первом домене приложения остаются независимыми от данных во втором домене.

Статические поля потока

Если известно, что некоторый фрагмент данных всегда является уникальным для сочетания потока и домена приложения, примените к статическому полю атрибут ThreadStaticAttribute. Это поле можно использовать аналогично любому другому статическому полю. Данные в этом поле являются уникальными для каждого потока, использующего поле.

Статические поля потоков обеспечивают более высокую производительность, чем области данных, и дают преимущества проверки типов во время компиляции.

Следует учитывать, что любой код конструктора класса будет работать с первым потоком в первом контексте, получающим доступ к полю. Поля во всех других потоках и во всех других контекстах в пределах того же домена приложения будут инициализированы значением null (Nothing в Visual Basic), если они имеют ссылочные типы, или значениями по умолчанию, если они имеют типы значения. Поэтому не следует полагаться на инициализацию статических полей потока конструкторами классов. Напротив, следует избегать инициализации статических полей потока и предполагать, что они инициализированы значениями null (Nothing) или значениями по умолчанию.

Области данных

Платформа .NET Framework предоставляет динамические области данных, которые являются уникальными для сочетания потока и домена приложения. Существует два типа областей данных: именованные и безымянные. Оба типа реализуются с помощью структуры LocalDataStoreSlot.

  • Для создания именованной области данных служит метод Thread.AllocateNamedDataSlot или Thread.GetNamedDataSlot. Чтобы получить ссылку на существующую именованную область, передайте ее имя методу GetNamedDataSlot.

  • Для создания безымянной области данных служит метод Thread.AllocateDataSlot.

Методы Thread.SetData и Thread.GetData используются для задания и получения данных в областях обоих типов. Эти статические методы всегда работают с данными в потоке, который выполняет их в текущий момент.

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

См. также

Ссылки

ContextStaticAttribute

Thread.GetNamedDataSlot

ThreadStaticAttribute

CallContext

Другие ресурсы

Управляемая поточность