Obtener el ID de hilo de un hilo

En C # al depurar hilos, por ejemplo, puede ver el ID de cada hilo.

No pude encontrar la manera de obtener el mismo hilo, programáticamente. Ni siquiera pude obtener el ID del hilo actual (en las propiedades del Thread.currentThread ).

Entonces, me pregunto cómo Visual Studio obtiene los ID de los hilos, y ¿hay alguna forma de obtener el manejo del hilo con id 2345 , por ejemplo?

GetThreadId devuelve la ID de un hilo nativo dado. Hay formas de hacerlo funcionar con hilos gestionados, estoy seguro de que todo lo que necesitas encontrar es el control del hilo y pasarlo a esa función.

GetCurrentThreadId devuelve el ID del hilo actual.

GetCurrentThreadId ha quedado obsoleto a partir de .NET 2.0: la forma recomendada es la propiedad Thread.CurrentThread.ManagedThreadId .

En C # al depurar hilos, por ejemplo, puede ver el ID de cada hilo.

Este será el ID de los hilos gestionados. ManagedThreadId es un miembro de Thread para que pueda obtener el Id desde cualquier objeto Thread . Esto te dará el ManagedThreadID actual:

 Thread.CurrentThread.ManagedThreadId 

Para obtener un hilo del sistema operativo por su ID de hilo del sistema operativo (no ManagedThreadID) , puede probar un poco de linq.

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

Parece que no hay forma de enumerar los hilos gestionados y ninguna relación entre ProcessThread y Thread, por lo que obtener un thread gestionado por su Id es difícil.

Para obtener más información sobre el subproceso administrado frente a no gestionado, consulte este artículo de MSDN .

Puede usar el AppDomain.GetCurrentThreadId desuso para obtener el ID del hilo que se está ejecutando actualmente. Este método usa un Invoke de API de Win32 método GetCurrentThreadID , y devolverá el ID de subproceso de Windows.

Este método está marcado como obsoleto porque el objeto .NET Thread no corresponde a un solo hilo de Windows, y como tal, no existe un ID estable que pueda ser devuelto por Windows para un hilo de .NET dado.

Vea la respuesta del configurador por más razones por las cuales este es el caso.

Para obtener el ID de SO use:

 AppDomain.GetCurrentThreadId() 

De acuerdo con MSDN :

Un ThreadId de sistema operativo no tiene una relación fija con un subproceso administrado, porque un host no administrado puede controlar la relación entre subprocesos administrados y no administrados. Específicamente, un host sofisticado puede usar la API CLR Hosting para progtwigr muchos hilos administrados contra el mismo hilo del sistema operativo, o para mover un hilo administrado entre diferentes subprocesos del sistema operativo.

Así que, básicamente, el objeto Thread no se corresponde necesariamente con un hilo del sistema operativo, por lo que no tiene el ID nativo expuesto.

Para aquellos a punto de piratear:

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

Para encontrar la Id actual de la cadena use – `Thread.CurrentThread.ManagedThreadId ‘. Pero en este caso es posible que necesite la identificación de la secuencia win32 actual – use pInvoke para obtenerla con esta función:

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

En primer lugar, deberá guardar la Id. De hilo administrado y la conexión de Id. De subprocesos win32: use un diccionario que asigne una Id. De win32 a la subunidad administrada.

Luego, para encontrar un hilo por su id, itere sobre el hilo del proceso usando Process.GetCurrentProcess (). Threads y encuentre el hilo con ese ID:

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

Desde el código administrado, tiene acceso a las instancias del tipo de Thread para cada subproceso administrado. Thread encapsula el concepto de un hilo del sistema operativo y, a partir del CLR actual, existe una correspondencia uno a uno con los hilos gestionados y los hilos del sistema operativo. Sin embargo, este es un detalle de implementación, que puede cambiar en el futuro.

La ID que Visual Studio muestra es en realidad la ID del hilo del sistema operativo. Esto no es lo mismo que el ID de subproceso administrado como lo sugieren varias respuestas.

El tipo de Thread incluye un campo privado miembro de DONT_USE_InternalThread llamado DONT_USE_InternalThread , que apunta a la estructura del sistema operativo subyacente. Sin embargo, como esto es realmente un detalle de implementación, no es aconsejable buscar esta OMI. Y el nombre indica que no deberías confiar en esto.

System.Threading.Thread.CurrentThread.Name

 System.Threading.Thread.CurrentThread.ManagedThreadId 

El desplazamiento en Windows 10 es 0x022C (aplicación x64-bit) y 0x0160 (aplicación x32-bit):

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

Puede usar Thread.GetHashCode, que devuelve el ID del hilo administrado. Si piensas en el propósito de GetHashCode, tiene sentido, debe ser un identificador único (por ejemplo, clave en un diccionario) para el objeto (el hilo).

La fuente de referencia para la clase Thread es instructiva aquí. (Por supuesto, una implementación particular de .NET puede no estar basada en este código fuente, pero para fines de depuración me arriesgaré).

GetHashCode “proporciona este código hash para algoritmos que necesitan verificaciones rápidas de la igualdad de objetos”, por lo que es adecuado para verificar la igualdad de subprocesos, por ejemplo, para afirmar que un método en particular se está ejecutando en el subproceso desde el que lo solicitó.