Verwaltetes und nicht verwaltetes Threading in Microsoft Windows
Aktualisiert: November 2007
Alle Threads, einschließlich derjenigen, die durch die Common Language Runtime erstellt wurden, und derjenigen, die außerhalb davon erstellt wurden und zur Ausführung von Code in die verwaltete Umgebung versetzt wurden, werden durch die Thread-Klasse verwaltet. Durch den Prozess der Common Language Runtime werden alle Threads überwacht, die jemals Code innerhalb der verwalteten Ausführungsumgebung ausgeführt haben. Andere Threads werden nicht verfolgt. Threads gelangen über COM-Interop (durch die Common Language Runtime werden verwaltete Objekte für die nicht verwalteten Bereiche als COM-Objekte verfügbar gemacht), die COM-Funktion DllGetClassObject() und über Plattformaufrufe in die verwaltete Ausführungsumgebung.
Wenn ein nicht verwalteter Thread z. B. durch einen COM Callable Wrapper in die Common Language Runtime versetzt wird, durchsucht das System den lokalen Threadspeicher dieses Threads nach einem internen verwalteten Thread-Objekt. Wurde ein solches gefunden, ist die Common Language Runtime über diesen Thread bereits informiert. Andernfalls wird ein neues Thread-Objekt erstellt und im lokalen Threadspeicher des betreffenden Threads installiert.
Bei verwaltetem Threading ist Thread.GetHashCode die stabile verwaltete Threadidentifikation. Diese Threadidentifikation gerät während der gesamten Lebensdauer des betreffenden Threads niemals mit dem Wert irgendeines anderen Threads in Konflikt, unabhängig von der Anwendungsdomäne, aus der dieser Wert abgerufen wurde.
Hinweis: |
---|
Die ThreadId eines Betriebssystems hat keine festgelegte Beziehung zu einem verwalteten Thread, da ein nicht verwalteter Host die Beziehung zwischen verwalteten und nicht verwalteten Threads steuern kann. Insbesondere kann ein hoch entwickelter Host unter Verwendung der Fiber-API die Ablaufplanung vieler verwalteter Threads durch denselben Betriebssystemthread ausführen oder einen verwalteten Thread zwischen verschiedenen Betriebssystemthreads verschieben. |
Zuordnen von Win32-Threading zu verwaltetem Threading
In der folgenden Tabelle werden Win32-Threadingelemente ihrer ungefähren Entsprechung in Common Language Runtime zugeordnet. Beachten Sie, dass diese Zuordnung keine identische Funktionalität widerspiegelt. TerminateThread beispielsweise führt weder finally-Klauseln aus noch gibt es Ressourcen frei und kann auch nicht abgebrochen werden. Thread.Abort führt jedoch den gesamten Rollbackcode aus, gewinnt alle Ressourcen zurück und kann mithilfe von ResetAbort abgebrochen werden. Lesen Sie die Dokumentation genau durch, ehe Sie Rückschlüsse auf die jeweilige Funktionalität ziehen.
In Win32 |
In Common Language Runtime |
---|---|
CreateThread |
Eine Kombination aus Thread und ThreadStart. |
TerminateThread |
|
SuspendThread |
|
ResumeThread |
|
Sleep |
|
WaitForSingleObject beim Threadhandle |
|
ExitThread |
Keine Entsprechung |
GetCurrentThread |
|
SetThreadPriority |
|
Keine Entsprechung |
|
Keine Entsprechung |
|
Verwandt mit CoInitializeEx (OLE32.DLL) |
Verwaltete Threads und COM-Apartments
Ein verwalteter Thread kann markiert werden, um anzuzeigen, dass er ein Singlethread- oder Multithread-Apartment hosten wird. Die Methoden GetApartmentState, SetApartmentState und TrySetApartmentState der Thread-Klasse werden zurückgegeben und weisen den Apartmentzustand eines Threads zu. Wenn kein Zustand festgelegt wurde, wird GetApartmentStateApartmentState.Unknown zurückgegeben.
Hinweis: |
---|
In den .NET Framework-Versionen 1.0 und 1.1 wird der Apartmentzustand mithilfe der ApartmentState-Eigenschaft abgerufen und festgelegt. |
Die Eigenschaft kann nur festgelegt werden, wenn sich der Thread im ThreadState.Unstarted-Zustand befindet. Diese Eigenschaft kann pro Thread nur einmal festgelegt werden.
Wenn der Apartmentzustand festgelegt wird, bevor die Ausführung des Threads gestartet wird, wird der Thread als Multithread-Apartment (MTA) initialisiert. Der Finalizerthread sowie alle Threads, die durch ThreadPool gesteuert werden, weisen den Zustand MTA auf.
Wichtiger Hinweis: |
---|
Anwendungsstartcode kann den Apartmentzustand nur steuern, indem das MTAThreadAttribute oder das STAThreadAttribute auf den Einstiegspunkt der Prozedur angewendet wird. In den .NET Framework-Versionen 1.0 und 1.1 kann die ApartmentState-Eigenschaft als erste Codezeile festgelegt werden. Dies ist in .NET Framework, Version 2.0, nicht zulässig. |
Verwaltete, für COM verfügbare Objekte verhalten sich, als ob sie den Freethreadmarshaller zusammengesetzt hätten. Das bedeutet, dass sie von jedem beliebigen COM-Apartment aus auf Freethreading basierend aufgerufen werden können. Die einzigen verwalteten Objekte, die dieses Verhalten nicht aufweisen, sind die von ServicedComponent abgeleiteten Objekte.
In verwalteten Bereichen wird SynchronizationAttribute nicht unterstützt, außer bei der Verwendung von Kontexten und kontextgebundenen verwalteten Instanzen. Bei der Verwendung von EnterpriseServices muss das Objekt von ServicedComponent abgeleitet sein (das wiederum von ContextBoundObject abgeleitet ist).
Der Aufruf von COM-Objekten durch verwalteten Code erfolgt immer nach COM-Regeln. Das heißt, der Aufruf erfolgt über COM-Apartmentproxys und COM+ 1.0-Kontextwrapper, wie von OLE32 vorgeschrieben.
Blockieren
Wenn ein Thread einen nicht verwalteten Aufruf des Betriebssystems vornimmt, das den Thread in nicht verwaltetem Code blockiert, steuert die Laufzeit diesen für Thread.Interrupt oder Thread.Abort nicht. Bei Thread.Abort markiert die Laufzeit den Thread für Abort und steuert diesen dann wieder, wenn er wieder von verwaltetem Code verarbeitet wird. Verwaltetes Blockieren ist nicht verwaltetem Blockieren vorzuziehen. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers usw. regieren auf Thread.Interrupt und auf Thread.Abort. Wenn sich der Thread in einem Singlethread-Apartment befindet, leiten alle diese verwalteten Blockiervorgänge ordnungsgemäß Meldungen in das Apartment weiterleiten, während der Thread blockiert ist.