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

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

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

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

Сопоставление потоков 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

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

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

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

Внимание

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

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

В управляемом коде отсутствует поддержка SynchronizationAttribute , если только вы не используете контексты и контекстно-привязанные управляемые экземпляры. Если вы используете корпоративные службы, ваш объект должен быть производным от 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. Кроме того, если ваш поток находится в однопотоковом подразделении, все эти операции управляемой блокировки будут корректно выдавать сообщения в ваше подразделение, пока поток находится в заблокированном состоянии.

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

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

См. также