work with threads thread net multiple example espaƱol book c# .net multithreading

c# - with - Obteniendo el ID de hilo de un hilo



thread net core (11)

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

No pude encontrar una manera de obtener ese mismo hilo, mediante programación. Ni siquiera pude obtener el ID del subproceso actual (en las propiedades de Thread.currentThread ).

Entonces, me pregunto cómo obtiene Visual Studio los identificadores de los subprocesos, y ¿hay alguna manera de obtener el identificador del subproceso con el id 2345 , por ejemplo?


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

Estos serán los identificadores de los hilos gestionados. ManagedThreadId es un miembro de Thread por lo que puede obtener la ID de cualquier objeto Thread . Esto te dará el Thread.CurrentThread.ManagedThreadId actual:

Thread.CurrentThread.ManagedThreadId

Para obtener un subproceso de sistema operativo por su ID de hilo de sistema operativo (no ManagedThreadID) , puedes 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 manera de enumerar los subprocesos administrados y no hay relación entre ProcessThread y Thread, por lo que obtener un subproceso administrado por su ID es una tarea difícil.

Para obtener más detalles sobre los subprocesos administrados y no administrados, vea este artículo de MSDN .


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

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

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


El desplazamiento bajo Windows 10 es 0x022C (aplicación de x64 bits) y 0x0160 (aplicación de x32 bits):

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


Para aquellos a punto de hackear:

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 el ID de hilo actual use - `Thread.CurrentThread.ManagedThreadId ''. Pero en este caso, es posible que necesite el ID de subproceso de win32 actual; use pInvoke para obtenerlo con esta función:

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

Primero deberá guardar la conexión del ID del hilo administrado y la del ID del hilo win32: use un diccionario que asigne un ID de Win32 al hilo administrado.

Luego, para encontrar un subproceso por su iteración de id sobre el subproceso del proceso utilizando Process.GetCurrentProcess (). Subprocesos y encuentre el subproceso con ese id:

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


Para obtener el ID del sistema operativo:

AppDomain.GetCurrentThreadId()


Puede usar Thread.GetHashCode, que devuelve la ID del hilo administrado. Si piensa en el propósito de GetHashCode, esto tiene mucho 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 propósitos de depuración, arriesgaré).

GetHashCode "proporciona este código hash para algoritmos que necesitan comprobaciones 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 particular se está ejecutando en el subproceso desde el que se llamó.


Puede usar el AppDomain.GetCurrentThreadId desuso para obtener el ID del subproceso que se está ejecutando actualmente. Este método utiliza un PInvoke al método GetCurrentThreadID de la API de Win32 y devolverá el ID de subproceso de Windows.

Este método está marcado como obsoleto porque el objeto de subproceso de .NET no corresponde a un solo subproceso de Windows y, como tal, no hay una ID estable que Windows pueda devolver para un subproceso de .NET determinado.

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


Según MSDN :

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

Básicamente, el objeto Thread no se corresponde necesariamente con un subproceso del sistema operativo, razón por la cual no tiene el ID nativo expuesto.


GetThreadId devuelve el ID de un subproceso nativo dado. Hay formas de hacerlo funcionar con subprocesos administrados, estoy seguro de que todo lo que necesita encontrar es el identificador del subproceso y pasarlo a esa función.

GetCurrentThreadId devuelve el ID del subproceso actual.

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


System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId