Threading managé et non managé dans WindowsManaged and unmanaged threading in Windows

La gestion de tous les threads s'effectue par le biais de la classe Thread , notamment les threads créés par le Common Language Runtime et ceux créés en dehors du runtime qui entrent dans l'environnement managé pour exécuter du code.Management of all threads is done through the Thread class, including threads created by the common language runtime and those created outside the runtime that enter the managed environment to execute code. Le runtime surveille tous les threads dans son processus qui ont exécuté du code dans l'environnement d'exécution managé.The runtime monitors all the threads in its process that have ever executed code within the managed execution environment. Il n'effectue le suivi d'aucun autre thread.It does not track any other threads. Les threads peuvent entrer dans l’environnement d’exécution managé via COM Interop (car le runtime expose les objets managés en tant qu’objets COM à l’environnement non managé), la fonction COM DllGetClassObject et l’appel de code non managé.Threads can enter the managed execution environment through COM interop (because the runtime exposes managed objects as COM objects to the unmanaged world), the COM DllGetClassObject function, and platform invoke.

Quand un thread non managé entre dans le runtime via, par exemple, un wrapper CCW (COM Callable Wrapper), le système vérifie si le magasin de threads local de ce thread contient un objet Thread managé interne.When an unmanaged thread enters the runtime through, for example, a COM callable wrapper, the system checks the thread-local store of that thread to look for an internal managed Thread object. Si un objet de ce type est trouvé, le runtime connaît déjà ce thread.If one is found, the runtime is already aware of this thread. Sinon, le runtime crée quand même un objet Thread et l’installe dans le magasin de threads local de ce thread.If it cannot find one, however, the runtime builds a new Thread object and installs it in the thread-local store of that thread.

Dans le modèle de thread managé, Thread.GetHashCode identifie les threads managés de manière stable.In managed threading, Thread.GetHashCode is the stable managed thread identification. Durant toute la durée de vie de votre thread, cette identification n'entre en conflit avec la valeur d'aucun autre thread, quel que soit le domaine d'application à partir duquel vous obtenez cette valeur.For the lifetime of your thread, it will not collide with the value from any other thread, regardless of the application domain from which you obtain this value.

Correspondance entre les éléments de thread Win32 et les éléments de thread managésMapping from Win32 threading to managed threading

Le tableau suivant établit une correspondance entre les éléments de thread Win32 et leurs équivalents approximatifs dans le runtime.The following table maps Win32 threading elements to their approximate runtime equivalent. Notez que cette mise en correspondance ne représente pas des fonctionnalités identiques.Note that this mapping does not represent identical functionality. Par exemple, TerminateThread n’exécute pas de clauses finally ou ne libère pas de ressources, et son exécution ne peut pas être empêchée.For example, TerminateThread does not execute finally clauses or free up resources, and cannot be prevented. Toutefois, Thread.Abort exécute tout votre code de restauration, récupère toutes les ressources et peut être refusé à l'aide de ResetAbort.However, Thread.Abort executes all your rollback code, reclaims all the resources, and can be denied using ResetAbort. Veillez à lire la documentation attentivement avant d'émettre des hypothèses sur les fonctionnalités.Be sure to read the documentation closely before making assumptions about functionality.

Dans Win32In Win32 Dans le Common Language RuntimeIn the common language runtime
CreateThreadCreateThread Combinaison de Thread et ThreadStartCombination of Thread and ThreadStart
TerminateThreadTerminateThread Thread.Abort
SuspendThreadSuspendThread Thread.Suspend
ResumeThreadResumeThread Thread.Resume
VeilleSleep Thread.Sleep
WaitForSingleObject sur le descripteur de threadWaitForSingleObject on the thread handle Thread.Join
ExitThreadExitThread Pas d'équivalentNo equivalent
GetCurrentThreadGetCurrentThread Thread.CurrentThread
SetThreadPrioritySetThreadPriority Thread.Priority
Pas d'équivalentNo equivalent Thread.Name
Pas d'équivalentNo equivalent Thread.IsBackground
Proche de CoInitializeEx (OLE32.DLL)Close to CoInitializeEx (OLE32.DLL) Thread.ApartmentState

Threads managés et cloisonnements COMManaged threads and COM apartments

Un thread managé peut être marqué pour indiquer qu’il hébergera un thread unique cloisonné ou un multithread cloisonné.A managed thread can be marked to indicate that it will host a single-threaded or multithreaded apartment. (Pour plus d’informations sur l’architecture de threads COM, consultez processus, threads et Apartments.) Les GetApartmentState SetApartmentState méthodes, et TrySetApartmentState de la Thread classe retournent et assignent l’état de cloisonnement d’un thread.(For more information on the COM threading architecture, see Processes, Threads, and Apartments.) The GetApartmentState, SetApartmentState, and TrySetApartmentState methods of the Thread class return and assign the apartment state of a thread. Si l'état n’a pas été défini, GetApartmentState retourne ApartmentState.Unknown.If the state has not been set, GetApartmentState returns ApartmentState.Unknown.

La propriété ne peut être définie que quand le thread se trouve dans l’état ThreadState.Unstarted et qu’une seule fois par thread.The property can be set only when the thread is in the ThreadState.Unstarted state; it can be set only once for a thread.

Si l'état de cloisonnement n'est pas défini avant que le thread n'ait démarré, celui-ci est initialisé en tant que cloisonnement multithread (MTA).If the apartment state is not set before the thread is started, the thread is initialized as a multithreaded apartment (MTA). Le thread finaliseur et tous les threads contrôlés par ThreadPool sont des threads MTA.The finalizer thread and all threads controlled by ThreadPool are MTA.

Important

Pour le code de démarrage d'application, la seule façon de contrôler l'état de cloisonnement consiste à appliquer les attributs MTAThreadAttribute ou STAThreadAttribute à la procédure de point d'entrée.For application startup code, the only way to control apartment state is to apply the MTAThreadAttribute or the STAThreadAttribute to the entry point procedure. Dans .NET Framework 1.0 et 1.1, la propriété ApartmentState peut être définie en tant que première ligne de code.In the .NET Framework 1.0 and 1.1, the ApartmentState property can be set as the first line of code. Cette opération n'est pas autorisée dans .NET Framework 2.0.This is not permitted in the .NET Framework 2.0.

Les objets managés exposés à COM se comportent comme s'ils avaient agrégé le marshaleur libre de threads.Managed objects that are exposed to COM behave as if they had aggregated the free-threaded marshaler. En d'autres termes, ils peuvent être appelés depuis n'importe quel cloisonnement COM d'une manière libre de threads.In other words, they can be called from any COM apartment in a free-threaded manner. Les seuls objets managés qui ne présentent pas ce comportement libre de threads sont les objets qui dérivent de ServicedComponent ou StandardOleMarshalObject.The only managed objects that do not exhibit this free-threaded behavior are those objects that derive from ServicedComponent or StandardOleMarshalObject.

Dans l'environnement managé, l'attribut SynchronizationAttribute n'est pas pris en charge, sauf si vous utilisez des contextes et des instances managées liées au contexte.In the managed world, there is no support for the SynchronizationAttribute unless you use contexts and context-bound managed instances. Si vous utilisez Enterprise Services, votre objet doit dériver de ServicedComponent (lui-même dérivé de ContextBoundObject).If you are using Enterprise Services, then your object must derive from ServicedComponent (which is itself derived from ContextBoundObject).

Quand un code managé appelle des objets COM, il suit systématiquement les règles COM.When managed code calls out to COM objects, it always follows COM rules. En d'autres termes, il effectue les appels par le biais de proxys de cloisonnement COM et de wrappers de contexte COM+ 1.0, conformément à OLE32.In other words, it calls through COM apartment proxies and COM+ 1.0 context wrappers as dictated by OLE32.

Problèmes de blocageBlocking issues

Si un thread effectue dans le système d'exploitation un appel non managé et qu'il se retrouve bloqué dans un code non managé, le runtime ne prend pas le contrôle du thread pour Thread.Interrupt ou Thread.Abort.If a thread makes an unmanaged call into the operating system that has blocked the thread in unmanaged code, the runtime will not take control of it for Thread.Interrupt or Thread.Abort. Dans le cas de Thread.Abort, le runtime marque le thread comme Abandonné et en prend le contrôle quand il revient dans le code managé.In the case of Thread.Abort, the runtime marks the thread for Abort and takes control of it when it re-enters managed code. Pensez à utiliser un blocage managé plutôt qu'un blocage non managé.It is preferable for you to use managed blocking rather than unmanaged blocking. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers, etc. réagissent tous à Thread.Interrupt et à Thread.Abort.WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers, and so on are all responsive to Thread.Interrupt and to Thread.Abort. En outre, si votre thread se trouve dans un cloisonnement monothread, toutes ces opérations de blocage managé pompent correctement les messages dans votre cloisonnement pendant que votre thread est bloqué.Also, if your thread is in a single-threaded apartment, all these managed blocking operations will correctly pump messages in your apartment while your thread is blocked.

Threads et fibresThreads and fibers

Le modèle de thread .NET ne prend pas en charge les fibres.The .NET threading model does not support fibers. Vous ne devez pas appeler dans n’importe quelle fonction non managée qui est implémentée à l’aide de fibres.You should not call into any unmanaged function that is implemented by using fibers. Ces appels peuvent entraîner un blocage du runtime .NET.Such calls may result in a crash of the .NET runtime.

Voir aussiSee also