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


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

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

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

В управляемом потоке Thread.GetHashCode — это стабильная идентификация управляемого потока. В течение всего времени существования потока он не будет сталкиваться со значением из любого другого потока независимо от домена приложения, из которого вы получаете это значение.

Сопоставление потоков Win32 с управляемыми потоками

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

В Win32 В среде общей среды выполнения (CLR)
CreateThread Сочетание потока и ThreadStart
Завершение проверки подлинности Thread.Abort
Приостановка Thread.Suspend
ResumeThread Thread.Resume
спящего Thread.Sleep
WaitForSingleObject в дескрипторе потока Thread.Join
ExitThread Нет эквивалента
GetCurrentThread Thread.CurrentThread
SetThreadPriority Thread.Priority
Нет эквивалента Thread.Name
Нет эквивалента Thread.IsBackground
Близко к CoInitializeEx (OLE32.DLL) Thread.ApartmentState

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

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

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

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

Это важно

Для кода запуска приложения единственным способом управления состоянием квартиры является применение MTAThreadAttribute или STAThreadAttribute к процедуре точки входа.

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

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

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

Критические препятствия

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

Нити и волокна

Модель потоков .NET не поддерживает волокна. Не следует вызывать неуправляемую функцию, реализуемую с помощью волокон. Такие вызовы могут привести к сбою среды выполнения .NET.

См. также