Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the _real_ thread id in a CLR "friendly" way?

Tags:

c#

winapi

As an exercise I was writing some code to display the O/S processes and O/S threads within a process (like Sysinternals process explorer does).

I found that .net's ManagedThreadId(s) are not the O/S thread ids. After a bit of reading I came across AppDomain.GetCurrentThreadId(). Unfortunately, that function is marked as "obsolete" (which could mean "not available" in the future). One solution I found is to use InteropServices to directly call the Win32 GetCurrentThreadId. I am fine with that but, it feels counter to the .net philosophy.

My question is: is there a CLR "friendly" way of obtaining the real id of the current thread ?

For reference, here is a snippet of code showing what I've tried so far. // 1 and // 2 display the correct thread id, // 3 and // 4 were attempts to obtain the same info in a CLR friendly way (but they don't work.)

Thank you for your help,

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);
}
like image 203
Hex440bx Avatar asked Apr 11 '11 16:04

Hex440bx


1 Answers

PInvoking into the GetCurrentThreadId is your best bet and will give you the correct information.

However I must warn you, there are very good reasons why the CLR doesn't provide this information: it's almost a completely useless value for managed code. It's perfectly legal from a CLR perspective for a single managed thread to be backed by several different native threads during it's lifetime. This means the result of GetCurrentThreadId can (and will) change throughout the course of a thread's lifetime.

In many applications this is not an observable phenomenon. In a UI application this won't actually happen because it's typically backed by an STA thread which is harder (usually even illegal) to swap out due to COM interop issues. So many developers are blissfully ignorant of this. However it's very easy to swap out MTA threads under the hood which is typically the execution context of a background thread.

like image 157
JaredPar Avatar answered Sep 21 '22 15:09

JaredPar