Obtener el ID del hilo de un hilo


En C# al depurar subprocesos, por ejemplo, puede ver el ID de cada subproceso.

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

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

Author: jonsca, 2009-11-05

11 answers

GetThreadId devuelve el ID de un determinado hilo nativo. Hay maneras de hacer que funcione con hilos administrados, estoy seguro, todo lo que necesita encontrar es el controlador de hilo y pasarlo a esa función.

GetCurrentThreadId devuelve el ID del hilo actual.

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

 381
Author: Blindy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-08 14:20:39

En C # al depurar subprocesos, por ejemplo, puede ver los subprocesos de cada subproceso ID.

Estos serán los Id de los subprocesos administrados. ManagedThreadId es un miembro de Thread por lo que puede obtener el Id de cualquier objeto Thread. Esto te dará el actual ManagedThreadId :

Thread.CurrentThread.ManagedThreadId

Para obtener un hilo de sistema operativo por su ID de hilo de 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 manera de enumerar los hilos administrados y no hay relación entre ProcessThread y el hilo, por lo que obtener un hilo administrado por su Id es difícil.

Para obtener más detalles sobre el subproceso Administrado vs.no administrado, consulte este arcticle de MSDN.

 65
Author: badbod99,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-30 15:04:58

Puede utilizar el obsoleto AppDomain.GetCurrentThreadId para obtener el ID del subproceso en ejecución. Este método utiliza un PInvoke para el método API Win32 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 único subproceso de Windows, y como tal no hay un ID estable que pueda devolver Windows para un subproceso. NET determinado.

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

 39
Author: Paul Turner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 09:26:32

Para obtener el ID del sistema operativo use:

AppDomain.GetCurrentThreadId()
 26
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 09:27:27

Según MSDN:

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

Así que básicamente, el Thread object no necesariamente corresponde a un subproceso del sistema operativo, por lo que no tiene el ID nativo expuesto.

 21
Author: configurator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 09:21:44

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;
    }
 12
Author: ezolotko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-12 16:02:21

Para encontrar el Id de subproceso actual use - `Thread.Hilo actual.Manejé el hilo". Pero en este caso es posible que necesite el id de hilo win32 actual: use PInvoke para obtenerlo con esta función:

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

Primero deberá guardar el id de subproceso administrado y la conexión de id de subproceso win32: use un diccionario que asigne un id de win32 al subproceso administrado.

Luego, para encontrar un hilo por su id, itere sobre el hilo del proceso usando Process.GetCurrentProcess().Hilos y encontrar el hilo con que id:

foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
{
     var managedThread = win32ToManagedThread[thread.id];
     if((managedThread.ManagedThreadId == threadId)
     {
         return managedThread;
     }
}
 8
Author: Dror Helper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 09:24:04

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

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

El Thread el tipo incluye un campo miembro 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 IMO. Y el nombre indica que no deberías confiar en esto.

 5
Author: Brian Rasmussen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 09:35:53

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId
 4
Author: Manu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 09:13:46

El desplazamiento en Windows 10 es 0x022C (x64-bit-Application) y 0x0160 (x32-bit-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
Author: Handball Reporter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-17 13:38:36

Puedes usar Thread.GetHashCode, que devuelve el ID del hilo administrado. Si piensas en el propósito de GetHashCode, esto tiene sentido needs necesita 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í. (Concedido, una implementación particular de. NET puede no estar basada en este código fuente, pero para propósitos de depuración me 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 comprobar la igualdad de subprocesos for por ejemplo, para afirmar que un método en particular se está ejecutando en el subproceso desde el que quería que se llamara.

 3
Author: yoyo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-22 20:13:28