2011-04-11 8 views
7

Como ejercicio, estaba escribiendo un código para mostrar los procesos O/S y subprocesos O/S dentro de un proceso (como lo hace el explorador de procesos Sysinternals).¿Cómo obtengo el ID del hilo _real_ de una manera CLR "amigable"?

Encontré que .NET's ManagedThreadId (s) no son los identificadores de subprocesos O/S. Después de leer un poco, me encontré con AppDomain.GetCurrentThreadId(). Desafortunadamente, esa función está marcada como "obsoleta" (lo que podría significar "no disponible" en el futuro). Una solución que encontré es usar InteropServices para llamar directamente al GetCurrentThreadId de Win32. Estoy de acuerdo con eso, pero se opone a la filosofía .net.

Mi pregunta es: ¿hay una forma CLR "amigable" de obtener la identificación real del hilo actual?

Como referencia, aquí hay un fragmento de código que muestra lo que he intentado hasta ahora. // 1 y // 2 muestran el ID del hilo correcto, // 3 y // 4 intentaron obtener la misma información de forma CLR amigable (pero no funcionan).

Gracias por su ayuda ,

John.

[DllImport("kernel32.dll")] 
static extern int GetCurrentThreadId(); 

static void Main(string[] args) 
{ 
    // AppDomain.GetCurrentThreadId() is "obsolete" 

    int ThreadId1 = AppDomain.GetCurrentThreadId(); // 1 

    // not the ".net" way of doing things 

    int ThreadId2 = GetCurrentThreadId();    // 2 

    // "no joy" attempts to get the same results I got above 

    int ThreadId3 = Process.GetCurrentProcess().Threads[0].Id; // 3 
    int ThreadId4 = Thread.CurrentThread.ManagedThreadId;  // 4 


    Console.WriteLine("ThreadId1: {0}, ThreadId2: {1}, ThreadId3: {2}, " + 
        "ThreadId4: {3}", 
        ThreadId1, ThreadId2, ThreadId3, ThreadId4); 
} 
+2

¿Por qué querría una forma "amigable" de CLR para obtener datos de CLR "poco amigables" sobre los cuales solo puede ejecutar operaciones "hostiles" de CLR? – Polity

+0

@Polity: escribo utilidades del sistema y la mayoría de ellas no tienen nada que ver con .net. Si programo en .net, me gustaría ser "amigable" con .net incluso si la información que me interesa no está relacionada con el entorno .net. – Hex440bx

+0

Bueno, mi punto se mantiene válido :) no hay ninguna razón para construir parte de un automóvil de acero y la otra parte de madera. Al igual que no hay ninguna razón para obtener un threadID nativo en una forma amigable de .NET solo para usarlo con las API del sistema nativo. ¡Usar GetCurrentThreadId de Win32 es perfectamente válido en este caso! – Polity

Respuesta

9

PInvoking en el GetCurrentThreadId es su mejor apuesta y le dará la información correcta.

Sin embargo, debo advertirle que hay muy buenas razones por las cuales CLR no proporciona esta información: es casi un valor completamente inútil para el código administrado. Es perfectamente legal desde una perspectiva CLR para un subproceso administrado único respaldado por varios subprocesos nativos diferentes durante su vida útil. Esto significa que el resultado de GetCurrentThreadId puede (y cambiará) a lo largo de la vida útil de un hilo.

En muchas aplicaciones esto no es un fenómeno observable. En una aplicación de interfaz de usuario esto no sucederá porque normalmente está respaldado por un subproceso STA que es más difícil (por lo general, incluso ilegal) para intercambiar debido a problemas de interoperabilidad COM. Muchos desarrolladores son felizmente ignorantes de esto. Sin embargo, es muy fácil intercambiar subprocesos MTA bajo el capó, que generalmente es el contexto de ejecución de un hilo de fondo.

+0

gracias. Soy consciente de la diferencia entre los hilos .net y los hilos O/S (por eso mencioné el Process Explorer de Sysinternals). De su respuesta, deduzco que no hay forma de CLR de obtener el hilo actual de O/S que no sea PInvoking. Esperaré por otras sugerencias antes de elegir una respuesta. – Hex440bx

+0

@ Hex440bx Estoy bastante seguro de que cada forma de obtener el ID nativo del código administrado quedó obsoleta en 2.0. – JaredPar

-1

Es obsoleto por una razón; la idea es que en el futuro, el ID del hilo "real" podría no ser constante o podría ser compartido entre hilos .NET.

+0

@Kieren: No voy a la información para "manipular" algo en .net, lo usaré solo en el nivel O/S (como Process Explorer, por ejemplo).) – Hex440bx

+0

La contradicción parece ser que estás buscando el ID del hilo actual, que tiene los problemas que mencioné anteriormente; el punto es que una cadena .NET no es necesariamente igual a una cadena O/S –

+0

@Kieren: entiendo su punto acerca de los hilos .net y O/S. Lo que estoy diciendo es que, si quisiera escribir una utilidad como Process Explorer usando C# (y .net obviamente), podría hacerse permaneciendo fiel a la filosofía .net mientras proporciona información que sea precisa en el nivel O/S. – Hex440bx

Cuestiones relacionadas