Subprocesamiento administrado y no administrado en Windows
La administración de todos los subprocesos se realiza mediante la clase Thread , incluidos los subprocesos creados por Common Language Runtime y los creados fuera del runtime que entran en el entorno administrado para ejecutar código. El runtime supervisa todos los subprocesos del proceso que han ejecutado alguna vez código en el entorno de ejecución administrado. No realiza un seguimiento de ningún otro subproceso. Los subprocesos pueden acceder al entorno de ejecución administrado a través de la interoperabilidad COM (porque el runtime expone los objetos administrados como objetos COM a los entornos no administrados), la función COM DllGetClassObject y la invocación de plataforma.
Cuando un subproceso no administrado entra en el runtime a través de, por ejemplo, un contenedor CCW, el sistema comprueba el almacén local del subproceso para buscar un objeto Thread administrado interno. Si se encuentra uno, el runtime ya tiene en cuenta este subproceso. Si no lo encuentra, el runtime compila un nuevo objeto Thread y lo instala en el almacén local de ese subproceso.
En los subprocesos administrados, Thread.GetHashCode es la identificación del subproceso administrado estable. En cuanto a la duración de su subproceso, no estará en conflicto con el valor de ningún otro subproceso, independientemente del dominio de la aplicación del que obtiene este valor.
Asignación de subprocesos de Win32 a subprocesos administrados
En la tabla siguiente se asignan elementos de subproceso de Win32 a sus equivalentes de runtime aproximados. Tenga en cuenta que esta asignación no representa una funcionalidad idéntica. Por ejemplo, TerminateThread no ejecuta cláusulas finally ni libera recursos, y no se puede evitar. No obstante, Thread.Abort ejecuta todo su código de reversión, recupera todos los recursos y se puede denegar con ResetAbort. Asegúrese de leer detenidamente la documentación y no realice suposiciones sobre la funcionalidad.
En Win32 | En Common Language Runtime |
---|---|
CreateThread | Combinación de Thread y ThreadStart |
TerminateThread | Thread.Abort |
SuspendThread | Thread.Suspend |
ResumeThread | Thread.Resume |
Sleep | Thread.Sleep |
WaitForSingleObject en el identificador de subproceso | Thread.Join |
ExitThread | No equivalente |
GetCurrentThread | Thread.CurrentThread |
SetThreadPriority | Thread.Priority |
No equivalente | Thread.Name |
No equivalente | Thread.IsBackground |
Cercano a CoInitializeEx (OLE32.DLL) | Thread.ApartmentState |
Subprocesos administrados y apartamentos COM
Un subproceso administrado se puede marcar para indicar que hospedará un contenedor uniproceso o multiproceso . (Para más información sobre la arquitectura de subprocesos COM, consulte Procesos, subprocesos y contenedores). Los métodos GetApartmentState, SetApartmentState y TrySetApartmentState de la clase Thread devuelven y asignan el estado de contenedor de un subproceso. Si el estado no se ha establecido, GetApartmentState devuelve ApartmentState.Unknown.
La propiedad solo se puede establecer cuando el estado del subproceso es ThreadState.Unstarted y únicamente una vez por subproceso.
Si el estado de contenedor no se establece antes de que se inicie el subproceso, el subproceso se inicializa como un contenedor multiproceso (MTA). El subproceso de finalizador y todos los subprocesos controlados por ThreadPool son MTA.
Importante
Para el código de inicio de aplicación, la única manera de controlar el estado de contenedor es aplicar MTAThreadAttribute o STAThreadAttribute al procedimiento de punto de entrada.
Los objetos administrados que están expuestos a COM se comportan como si tuviesen agregado el cálculo de referencias con subprocesamiento libre. En otras palabras, se pueden llamar desde cualquier apartamento COM en un modo de subprocesamiento libre. Los únicos objetos administrados que no muestran este comportamiento de subprocesamiento libre son aquellos que derivan de ServicedComponent o StandardOleMarshalObject.
En el ámbito de recursos administrados, SynchronizationAttribute no se admite a menos que se usen contextos e instancias administradas asociadas a un contexto. Si usa Enterprise Services, entonces su objeto debe derivarse de ServicedComponent (que a su vez se deriva de ContextBoundObject).
Cuando el código administrado llama a objetos COM, siempre sigue reglas COM. En otras palabras, el código llama a través de los proxy de apartamentos COM y contenedores de contexto COM+ 1.0, según lo dictado por OLE32.
Problemas de bloqueo
Si un subproceso realiza una llamada no administrada al sistema operativo que ha bloqueado el subproceso en código no administrado, el runtime no tomará el control de él para Thread.Interrupt ni Thread.Abort. En el caso de Thread.Abort, el runtime marca el subproceso para Abort y toma el control de él cuando vuelve a introducir código administrado. Lo preferible para usted es usar un bloqueo administrado en vez de no administrado. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizersy demás responden todos a Thread.Interrupt y Thread.Abort. Además, si su subproceso está en un contenedor uniproceso, todas estas operaciones de bloqueo administrado suministrarán correctamente mensajes en su contenedor mientras el subproceso está bloqueado.
Subprocesos y fibras
El modelo de subprocesos de .NET no admite fibras. No debe llamar a ninguna función no administrada que se implementa mediante fibras. Tales llamadas pueden producir un bloqueo de runtime de .NET.