Verwaltetes und nicht verwaltetes Threading in Windows

Die Verwaltung aller Threads erfolgt über die Thread -Klasse, einschließlich Threads, die von der Common Language Runtime erstellt werden, und Threads, die außerhalb der Runtime erstellt werden und in die verwaltete Umgebung eintreten, um Code auszuführen. Die Laufzeit überwacht alle Threads in ihrem Prozess, die jemals Code in der verwalteten Ausführungsumgebung ausgeführt haben. Sie verfolgt keine anderen Threads. Threads können über COM-Interop (da die Runtime verwaltete Objekte als COM-Objekte für die nicht verwaltete Umgebung verfügbar macht), über die COM- DllGetClassObject -Funktion und über einen Plattformaufruf in die verwaltete Ausführungsumgebung eintreten.

Wenn ein nicht verwalteter Thread beispielsweise über einen COM Callable Wrapper in die Runtime eintritt, überprüft das System den lokalen Threadspeicher auf ein intern verwaltetes Thread -Objekt. Wird eins gefunden, ist der Laufzeit dieser Thread bereits bewusst. Wird keins gefunden, erstellt die Runtime jedoch ein neues Thread -Objekt und installiert es im lokalen Threadspeicher dieses Threads.

Beim verwalteten Threading ist Thread.GetHashCode die stabile ID für den verwalteten Thread. Für die Lebensdauer des Threads wird kein Konflikt mit dem Wert eines anderen Threads entstehen, unabhängig von der Anwendungsdomäne, aus der Sie diesen Wert erhalten.

Zuordnen zwischen Win32-Threading und verwaltetem Threading

In der folgenden Tabelle sind Win32-Threadingelemente ihren ungefähren Laufzeitentsprechungen zugeordnet. Beachten Sie, dass diese Zuordnung keine identische Funktionalität darstellt. TerminateThread führt beispielsweise keine finally -Klauseln aus, setzt keine Ressourcen frei und kann nicht vermieden werden. Thread.Abort jedoch führt Ihren gesamten Rollbackcode aus, gibt alle Ressourcen frei und kann über ResetAbortverweigert werden. Lesen Sie unbedingt sorgfältig die Dokumentation, bevor Sie Annahmen über die Funktionalität treffen.

In Win32 In der Common Language Runtime
CreateThread Kombination aus Thread und ThreadStart
TerminateThread Thread.Abort
SuspendThread Thread.Suspend
ResumeThread Thread.Resume
Sleep Thread.Sleep
WaitForSingleObject im Threadhandle Thread.Join
ExitThread Keine Entsprechung
GetCurrentThread Thread.CurrentThread
SetThreadPriority Thread.Priority
Keine Entsprechung Thread.Name
Keine Entsprechung Thread.IsBackground
Nahe an CoInitializeEx (OLE32.DLL) Thread.ApartmentState

Verwaltete Threads und COM-Apartments

Ein verwalteter Thread kann gekennzeichnet werden, um anzugeben, dass er ein Singlethread - oder ein Multithread -Apartment hostet. (Weitere Informationen zur COM-Threadingarchitektur finden Sie unter Prozesse, Threads und Apartments.) Die Methoden GetApartmentState, SetApartmentState und TrySetApartmentState der Thread-Klasse geben den Apartmentzustand eines Threads zurück und weisen ihn zu. Wurde der Zustand nicht festgelegt, gibt GetApartmentState den Wert ApartmentState.Unknown zurück.

Die Eigenschaft kann nur festgelegt werden, wenn sich der Thread im Zustand ThreadState.Unstarted befindet. Die Eigenschaft kann für einen Thread nur einmal festgelegt werden.

Wenn der Apartmentzustand nicht festgelegt ist, bevor der Thread gestartet wird, wird der Thread als Multithread-Apartment (MTA) initialisiert. Der Finalizerthread und alle von ThreadPool gesteuerten Threads sind MTAs.

Wichtig

Bei Anwendungsstartcode besteht die einzige Möglichkeit zum Steuern des Apartmentstatus darin, MTAThreadAttribute oder STAThreadAttribute für das Einstiegspunktverfahren anzuwenden.

Verwaltete Objekte, die für COM verfügbar gemacht werden, verhalten sich, als hätten sie den Freethread-Marshaller aggregiert. Anders gesagt können Sie von jedem COM-Apartment auf eine Freethreadweise aufgerufen werden. Die einzigen verwalteten Objekte, die dieses Freethread-Verhalten nicht zeigen, die Objekte, die von ServicedComponent oder StandardOleMarshalObject abgeleitet werden.

In der verwalteten Umgebung wird SynchronizationAttribute nur unterstützt, wenn Sie Kontexte und kontextgebundene verwaltete Instanzen verwenden. Wenn Sie Enterprise Services verwenden, muss Ihr Objekt aus der ServicedComponent-Klasse abgeleitet sein (die wiederum selbst aus ContextBoundObject abgeleitet ist).

Wenn verwalteter Code COM-Objekte aufruft, befolgt er immer COM-Regeln. Anders gesagt erfolgt der Aufruf über COM-Apartmentproxies und COM+ 1.0-Kontext-Wrapper, wie von OLE32 vorgegeben.

Blockierprobleme

Wenn ein Thread einen nicht verwalteten Aufruf in der Betriebssystem vornimmt, das den Thread in nicht verwaltetem Code blockiert hat, übernimmt die Laufzeit keine Kontrolle darüber für Thread.Interrupt oder Thread.Abort. Im Fall von Thread.Abortkennzeichnet die Laufzeit den Thread für Abort und übernimmt die Kontrolle darüber, wenn der verwaltete Code erneut eingegeben wird. Sie sollten vorzugsweise die verwaltete Blockierung statt die nicht verwaltete Blockierung verwenden. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers usw. reagieren alle auf Thread.Interrupt und Thread.Abort. Wenn sich Ihr Thread in einem Singlethread-Apartment befindet, werden all diese verwalteten Blockierungsvorgänge außerdem Meldungen in Ihr Apartment verschieben, während Ihr Thread blockiert ist.

Threads und Fibers

Das .NET-Threadingmodell unterstützt keine Fibers. Sie sollten keine nicht verwaltete Funktion aufrufen, die mithilfe von Fibers implementiert wurde. Solche Aufrufe können zu einem Absturz der .NET-Runtime führen.

Weitere Informationen