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


Управляемые и неуправляемые потоки в Microsoft Windows

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

Управление всеми потоками осуществляется с помощью класса Thread, включая потоки, созданные средой CLR, а также потоки, созданные за пределами среды и использующие управляемую среду для выполнения кода. Среда выполнения отслеживает все потоки, когда либо выполнявшие код в управляемой среде выполнения. Другие потоки не отслеживаются. Потоки могут входить в среду CLR с помощью COM-взаимодействия (поскольку в неуправляемой среде управляемые объекты предоставляются другим приложениям в виде объектов COM), функции COM DllGetClassObject() или с помощью платформенного вызова.

Например, если неуправляемый поток входит в среду выполнения через вызываемую оболочку COM-вызовов, система проверяет локальное хранилище потоков данного потока для поиска внутреннего управляемого объекта Thread. Если объект найден, существование потока уже учтено в среде выполнения. Если объект не найден, среда выполнения создает новый объект Thread и помещает его в локальное хранилище потоков данного потока.

При использовании управляемых потоков Thread.GetHashCode является постоянным идентификатором управляемого потока. В течение всего времени жизни потока исключено его взаимодействие со значением из другого потока, независимо от домена приложения, в котором получено данное значение.

74169f59.alert_note(ru-ru,VS.90).gifПримечание.

Идентификационный номер потока ThreadId операционной системы не имеет жесткой взаимосвязи с управляемым потоком, так как неуправляемое основное приложение может контролировать взаимосвязь между управляемыми и неуправляемыми потоками. В частности, для планирования большого количества управляемых потоков относительно одного и того же потока операционной системы или для перемещения управляемого потока между различными потоками операционной системы в сложном основном приложении может использоваться интерфейс Fiber API.

Связь между управляемыми потоками и потоками Win32

В следующей таблице показано, как элементы потоков Win32 связаны с соответствующими элементами в среде выполнения. Обратите внимание, что данное отображение не предоставляет одинаковые функциональные возможности. Например, метод TerminateThread не выполняет предложения finally, не освобождает ресурсы и его нельзя запретить. Однако перегрузка Thread.Abort выполняет код возврата, возвращает все ресурсы, но может быть запрещена с помощью метода ResetAbort. Для получения полного представления о функциональных возможностях следует внимательно прочесть документацию.

В Win32

В среде CLR

CreateThread

Сочетание Thread и ThreadStart

TerminateThread

Thread.Abort

SuspendThread

Thread.Suspend

ResumeThread

Thread.Resume

Sleep

Thread.Sleep

WaitForSingleObject для дескриптора потока

Thread.Join

ExitThread

Нет эквивалента

GetCurrentThread

Thread.CurrentThread

SetThreadPriority

Thread.Priority

Нет эквивалента

Thread.Name

Нет эквивалента

Thread.IsBackground

Закрывается в CoInitializeEx (OLE32.DLL)

Thread.ApartmentState

Управляемые потоки и апартаменты COM

Управляемому потоку можно задать выполнение функций однопоточного или многопоточного апартамента. Методы GetApartmentState, SetApartmentState и TrySetApartmentState класса Thread возвращают и назначают состояние апартамента потока. Если это состояние не было установлено, метод GetApartmentState возвращает ApartmentState.Unknown.

74169f59.alert_note(ru-ru,VS.90).gifПримечание.

В .NET Framework версии 1.0 и 1.1 свойство ApartmentState используется для получения и установки состояния апартамента.

Свойство может быть установлено только в том случае, если поток находится в состоянии ThreadState.Unstarted; это свойство можно задать для потока только один раз.

Если состояние апартамента задано до запуска потока, поток инициализируется как многопоточный апартамент. Метод завершения и все потоки, управляемые ThreadPool, являются многопоточными апартаментами.

74169f59.alert_caution(ru-ru,VS.90).gifВажное примечание.

Единственным способом управления состоянием апартамента для кода запуска приложения является применение объекта MTAThreadAttribute или STAThreadAttribute к процедуре точки входа. В .NET Framework версий 1.0 и 1.1 свойство ApartmentState может быть установлено как первая строка кода. Это не разрешается в .NET Framework версии 2.0.

Управляемые объекты, предоставленные приложениям COM, функционируют как объекты, объединенные средством маршалинга свободных потоков. Другими словами, их можно вызвать из любого апартамента COM так же, как свободный поток. Единственными управляемыми объектами, не демонстрирующими такое поведение, не зависящее от потока, являются объекты, производные из ServicedComponent.

В управляемом мире отсутствует поддержка объекта SynchronizationAttribute, если только не используются контексты и управляемые экземпляры, привязанные к контексту. Если используется EnterpriseServices, то объект должен наследоваться из ServicedComponent (который, в свою очередь, наследуется из ContextBoundObject).

Обращение управляемого кода к объектам COM выполняется по правилам COM. Другими словами, вызов выполняется через прокси апартаментов COM и контекстные обертки COM+ 1.0 согласно OLE32.

Проблемы, связанные с блокировкой

Если поток выполняет неуправляемый вызов в операционную систему, которая заблокировала поток в неуправляемом коде, среда выполнения не получит управление этим потоком для метода Thread.Interrupt или Thread.Abort. В случае с Thread.Abort среда выполнения отмечает поток для Abort и принимает управление им при его возвращении в управляемый код. Вместо неуправляемой блокировки лучше использовать управляемую блокировку. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers и т. д. могут взаимодействовать с методом Thread.Interrupt и перегрузкой Thread.Abort. Также если поток находится в однопоточном апартаменте, все эти управляемые операции блокирования приведут к правильному отображению сообщений в апартаменте во время блокирования потока.

См. также

Ссылки

Thread.ApartmentState

Перечисление Threadstate

ServicedComponent

Thread

Monitor