Obtenir L'ID de thread à partir d'un thread

En C# lors du débogage des threads par exemple, vous pouvez voir L'ID de chaque thread.

Je n'ai pas pu trouver un moyen d'obtenir ce même thread, par programmation. Je ne pouvais même pas obtenir L'ID du thread actuel (dans les propriétés du Thread.currentThread).

Donc, je me demande comment Visual Studio obtenir l'Id de threads, et est-il un moyen d'obtenir la poignée du fil avec id 2345, par exemple?

259
demandé sur jonsca 2009-11-05 12:02:17

11 réponses

GetThreadId renvoie l'ID du thread natif. Il existe des moyens de le faire fonctionner avec des threads gérés, je suis sûr, tout ce que vous devez trouver est le handle de thread et le transmettre à cette fonction.

GetCurrentThreadId renvoie l'ID du thread courant.

GetCurrentThreadId a été obsolète à partir de. net 2.0: la manière recommandée est la Thread.CurrentThread.ManagedThreadId propriété.

381
répondu Blindy 2016-01-08 14:20:39

En C# lors du débogage des threads, par exemple, vous pouvez voir ID.

Ce seront Les Id des threads gérés. ManagedThreadId est un membre de Thread de sorte que vous pouvez obtenir l'Id de partir de n'importe quel Thread objet. Cela vous donnera le courant ManagedThreadID :

Thread.CurrentThread.ManagedThreadId

Pour obtenir un thread OS par son ID de thread OS (not ManagedThreadID) , Vous pouvez essayer un peu de linq.

int unmanagedId = 2345;
ProcessThread myThread = (from ProcessThread entry in Process.GetCurrentProcess().Threads
   where entry.Id == unmanagedId 
   select entry).First();

Il semble qu'il n'y ait aucun moyen d'énumérer les threads gérés et aucune relation entre ProcessThread et Thread, donc obtenir un thread géré par son Id est difficile.

Pour plus de détails sur les threads gérés et non gérés, voir CET arcticle MSDN.

65
répondu badbod99 2013-04-30 15:04:58

Vous pouvez utiliser le obsolète AppDomain.GetCurrentThreadId pour obtenir l'ID du thread en cours d'exécution. Cette méthode utilise un PInvoke à la méthode de L'API Win32 GetCurrentThreadID, et retournera L'ID de thread Windows.

Cette méthode est marquée comme obsolète car L'objet.net Thread ne correspond pas à un seul thread Windows, et en tant que tel, il n'y a pas d'ID stable qui peut être retourné par Windows pour un thread. net donné.

Voir la réponse du configurateur pour plus de raisons pour lesquelles c'est le cas.

39
répondu Paul Turner 2009-11-05 09:26:32

Pour obtenir L'ID du système d'exploitation, utilisez:

AppDomain.GetCurrentThreadId()
26
répondu Mark Byers 2009-11-05 09:27:27

Selon MSDN:

Un ThreadId du système d'exploitation n'a pas relation fixe à un géré thread, car un hôte non géré peut contrôler la relation entre threads gérés et non gérés. Plus précisément, un hôte sophistiqué peut utilisez L'API D'hébergement CLR pour planifier beaucoup de threads gérés contre le même thread du système d'exploitation, ou pour déplacer un thread géré entre différents threads du système d'exploitation.

Donc, fondamentalement, le Thread l'objet ne correspond pas nécessairement à un thread OS - c'est pourquoi il n'a pas l'ID natif exposé.

21
répondu configurator 2009-11-05 09:21:44

Pour ceux qui sont sur le point de pirater:

    public static int GetNativeThreadId(Thread thread)
    {
        var f = typeof(Thread).GetField("DONT_USE_InternalThread",
            BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

        var pInternalThread = (IntPtr)f.GetValue(thread);
        var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 548 : 348); // found by analyzing the memory
        return nativeId;
    }
12
répondu ezolotko 2013-07-12 16:02:21

Pour trouver l'Id de thread actuel, utilisez - ' Thread.CurrentThread.ManagedThreadId'. Mais dans ce cas, vous pourriez avoir besoin de l'id de thread win32 actuel-utilisez pInvoke pour l'obtenir avec cette fonction:

[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentWin32ThreadId();

Vous devez D'abord enregistrer l'id de thread géré et la connexion win32 thread id - utilisez un dictionnaire qui mappe un ID win32 au thread géré.

Ensuite, pour trouver un thread par son id, itérez sur le thread du processus en utilisant le processus.Fonction getcurrentprocess().Threads et trouver le fil avec cela id:

foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
{
     var managedThread = win32ToManagedThread[thread.id];
     if((managedThread.ManagedThreadId == threadId)
     {
         return managedThread;
     }
}
8
répondu Dror Helper 2009-11-05 09:24:04

À partir du code géré, vous avez accès aux instances du type Thread pour chaque thread géré. Thread encapsule le concept D'un thread OS et à partir du CLR actuel, il y a une correspondance un-à-un avec les threads gérés et les threads OS. Cependant, il s'agit d'un détail de mise en œuvre, qui peut changer à l'avenir.

L'ID affiché par Visual Studio est en fait L'ID du thread du système D'exploitation. C'est pas, le même que l'ID de thread géré comme suggéré par plusieurs réponses.

Le Le type Thread inclut un champ Membre IntPtr privé appelé DONT_USE_InternalThread, qui pointe vers la structure du système d'exploitation sous-jacente. Cependant, comme il s'agit vraiment d'un détail de mise en œuvre, il n'est pas conseillé de poursuivre cette OMI. Et le nom indique en quelque sorte que vous ne devriez pas compter sur cela.

5
répondu Brian Rasmussen 2009-11-05 09:35:53

Système.Le filetage.Fil de discussion.CurrentThread.Nom

System.Threading.Thread.CurrentThread.ManagedThreadId
4
répondu Manu 2009-11-05 09:13:46

Le décalage sous Windows 10 est 0x022C (64 bits) et la 0x0160 (32 bits de l'Application):

public static int GetNativeThreadId(Thread thread)
{
    var f = typeof(Thread).GetField("DONT_USE_InternalThread",
        BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

    var pInternalThread = (IntPtr)f.GetValue(thread);
    var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 0x022C : 0x0160); // found by analyzing the memory
    return nativeId;
}
4
répondu Handball Reporter 2017-10-17 13:38:36

Vous pouvez utiliser Thread.GetHashCode, qui renvoie L'ID de thread géré. Si vous pensez au but de GetHashCode, cela a du sens - il doit s'agir d'un identifiant unique (par exemple une clé dans un dictionnaire) pour l'objet (le thread).

La source de référence pour la classe de Thread est instructive ici. (Certes, une implémentation. net particulière Peut ne pas être basée sur ce code source, mais à des fins de débogage, je vais tenter ma chance.)

GetHashCode "fournit ce code de hachage pour les algorithmes qui ont besoin de vérifications rapides de l'égalité des objets", il est donc bien adapté pour vérifier L'égalité des threads-par exemple pour affirmer qu'une méthode particulière s'exécute sur le thread à partir duquel vous vouliez l'appeler.

3
répondu yoyo 2014-10-22 20:13:28