it-swarm.com.de

Abrufen der Thread-ID von einem Thread

In C # können Sie beispielsweise beim Debuggen von Threads die ID jedes Threads anzeigen.

Ich konnte keinen Weg finden, programmgesteuert denselben Thread zu erhalten. Ich konnte nicht einmal die ID des aktuellen Threads abrufen (in den Eigenschaften von Thread.currentThread).

Ich frage mich also, wie Visual Studio die IDs der Threads abruft und gibt es eine Möglichkeit, das Handle des Threads mit der ID 2345, beispielsweise?

298
LolaRun

GetThreadId gibt die ID eines bestimmten nativen Threads zurück. Ich bin sicher, Sie müssen nur das Thread-Handle finden und es an diese Funktion übergeben, damit es mit verwalteten Threads funktioniert.

GetCurrentThreadId gibt die ID des aktuellen Threads zurück.

GetCurrentThreadId ist seit .NET 2.0 veraltet. Empfohlen wird die Methode Thread.CurrentThread.ManagedThreadId Eigenschaft.

416
Blindy

In C # können Sie beispielsweise beim Debuggen von Threads die ID jedes Threads anzeigen.

Dies sind die IDs der verwalteten Threads. ManagedThreadId ist ein Mitglied von Thread, sodass Sie die ID von jedem Thread -Objekt abrufen können. Damit erhalten Sie die aktuelle ManagedThreadID :

Thread.CurrentThread.ManagedThreadId

Um einen OS-Thread anhand seiner OS-Thread-ID (nicht ManagedThreadID) zu ermitteln, können Sie ein wenig linq ausprobieren.

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

Es scheint, dass es keine Möglichkeit gibt, die verwalteten Threads und keine Beziehung zwischen ProcessThread und Thread aufzulisten. Daher ist es schwierig, einen verwalteten Thread anhand seiner ID zu ermitteln.

Weitere Informationen zu verwaltetem und nicht verwaltetem Threading finden Sie unter dieser MSDN-Artikel .

74
badbod99

Sie können das veraltete AppDomain.GetCurrentThreadId um die ID des aktuell laufenden Threads zu erhalten. Diese Methode verwendet ein PInvoke für die Win32-API-Methode GetCurrentThreadID und gibt die Windows-Thread-ID zurück.

Diese Methode wird als veraltet markiert, da das .NET-Thread-Objekt keinem einzelnen Windows-Thread entspricht und daher keine stabile ID vorhanden ist, die von Windows für einen bestimmten .NET-Thread zurückgegeben werden kann.

In der Antwort des Konfigurators finden Sie weitere Gründe, warum dies der Fall ist.

42
Paul Turner

Um die OS ID zu erhalten, verwenden Sie:

AppDomain.GetCurrentThreadId()
30
Mark Byers

Nach MSDN :

Eine Betriebssystem-Thread-ID hat keine feste Beziehung zu einem verwalteten Thread, da ein nicht verwalteter Host die Beziehung zwischen verwalteten und nicht verwalteten Threads steuern kann. Insbesondere kann ein anspruchsvoller Host die CLR-Hosting-API verwenden, um viele verwaltete Threads für denselben Betriebssystem-Thread zu planen oder einen verwalteten Thread zwischen verschiedenen Betriebssystem-Threads zu verschieben.

Daher entspricht das Thread -Objekt nicht unbedingt einem Betriebssystem-Thread - weshalb die native ID nicht verfügbar ist.

21
configurator

Für diejenigen, die kurz vor dem Hack stehen:

    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;
    }
14
ezolotko

Um die aktuelle Thread-ID zu ermitteln, verwenden Sie - `Thread.CurrentThread.ManagedThreadId '. In diesem Fall benötigen Sie möglicherweise die aktuelle win32-Thread-ID. Verwenden Sie pInvoke, um diese mit dieser Funktion abzurufen:

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

Zuerst müssen Sie die verwaltete Thread-ID und die Win32-Thread-ID-Verbindung speichern. Verwenden Sie ein Wörterbuch, das eine Win32-ID dem verwalteten Thread zuordnet.

Um einen Thread anhand seiner ID zu finden, iterieren Sie mit Process.GetCurrentProcess () über den Thread des Prozesses. Threads und suchen Sie den Thread mit dieser ID:

foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
{
     var managedThread = win32ToManagedThread[thread.id];
     if((managedThread.ManagedThreadId == threadId)
     {
         return managedThread;
     }
}
10
Dror Helper

Der Offset unter Windows 10 ist 0x022C (x64-Bit-Anwendung) und 0x0160 (x32-Bit-Anwendung):

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;
}
9

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId
5
Manu

Über verwalteten Code haben Sie Zugriff auf Instanzen des Typs Thread für jeden verwalteten Thread. Thread kapselt das Konzept eines Betriebssystemthreads und ab der aktuellen CLR gibt es eine Eins-zu-Eins-Entsprechung mit verwalteten Threads und Betriebssystemthreads. Dies ist jedoch ein Implementierungsdetail, das sich in Zukunft ändern kann.

Die von Visual Studio angezeigte ID ist eigentlich die Betriebssystem-Thread-ID. Dies ist nicht dasselbe wie die ID des verwalteten Threads, wie in mehreren Antworten vorgeschlagen.

Der Typ Thread enthält ein privates IntPtr-Mitgliedsfeld mit dem Namen DONT_USE_InternalThread, das auf die zugrunde liegende Betriebssystemstruktur verweist. Da es sich jedoch in Wirklichkeit um ein Implementierungsdetail handelt, ist es nicht ratsam, diese IMO fortzusetzen. Und der Name deutet darauf hin, dass Sie sich nicht darauf verlassen sollten.

5
Brian Rasmussen

Sie können Thread.GetHashCode verwenden, der die ID des verwalteten Threads zurückgibt. Wenn Sie über den Zweck von GetHashCode nachdenken, ist dies sinnvoll - es muss eine eindeutige Kennung (z. B. Schlüssel in einem Wörterbuch) für das Objekt (den Thread) sein.

Die Referenzquelle für die Thread-Klasse ist hier lehrreich. (Zugegeben, eine bestimmte .NET-Implementierung basiert möglicherweise nicht auf diesem Quellcode, aber für Debugging-Zwecke gehe ich mein Risiko ein.)

GetHashCode "Stellt diesen Hash-Code für Algorithmen bereit, die eine schnelle Überprüfung der Objektgleichheit benötigen". Damit eignet es sich gut zur Überprüfung der Thread-Gleichheit, um beispielsweise zu bestätigen, dass eine bestimmte Methode auf dem von Ihnen ausgewählten Thread ausgeführt wird wollte es aus angerufen.

3
yoyo