How to get thread id for a managed thread?


This question comes up from time to time. The answer is, there is no explicit numeric thread id for managed thread today in .Net framework.

Now if you do need a numeric thread id for whatever reason, you can use System.Threading.Thread.GetHashCode(). This is documented here.  

[update: In .Net framework 2.0, you can use System.Threading.Thread.ManagedThreadId to get a numeric thread id.]

Comments (10)

  1. sdfsadf says:

    gsfasdfdsa

  2. sdfsadf says:

    gsfasdfdsa

  3. Sami Vaaraniemi says:

    Thread.GetHashCode() is good for most uses, but if you need the actual system thread id (e.g., for debugging purposes), use AppDomain.GetCurrentThreadId().

  4. Fabrice says:

    Maybe Process.Threads[n].Id can help also?

  5. Neither AppDomain.GetCurrentThreadId or Process.Threads.Id is the right answer. The reason is stated in the MSDN link provided above.Specifically, those two APIs return the unmanaged system thread id, which is theory, has nothing to do with managed thread.

    quote from the link:

    <quote>

    In managed threading, Thread.GetHashCode is the stable managed thread identification. For the lifetime of your thread, it will not collide with the value from any other thread, regardless of the application domain from which you obtain this value.

    Note An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. Specifically, a sophisticated host can use the Fiber API to schedule many managed threads against the same operating system thread, or to move a managed thread among different operating system threads.

    </quote>

  6. Jerry says:

    You can pull the switch and delete the file. Works for me.

  7. Alistair Young says:

    I’m needing, for sundry reasons, to recreate the Exim message-ID generation algorithm in .NET. It uses the process ID as part of what it generates, to ensure uniqueness across the system, which I’m replacing with the Win32 thread ID (as this class may be called from multithreaded apps which the Unix original didn’t have to worry about).

    So, to get to the point, is Thread.GetHashCode guaranteed to be unique across all managed apps in the system the way the Win32 thread ID is, or do I need to use the unmanaged ID?

    (If so, I realise this may break in, say, the Fiber case you mention, but I have to figure that’s got less chance to come up than this class running in multiple processes on the same system; unfortunately, I don’t have the ability to change the format to take all of these into account.)

  8. You better create a GUID and use that GUID for your purpose.

    Process ID is not unique in windows. Windows will recycle procoess ID when your app exists.

    For the same reason, Win32 thread ID is not unique.

    Thread.GetHashCode, of course, is not unique across processes neither.

  9. Alistair Young says:

    Thanks for your response. The only problem with using a GUID is that I have to be compatible with the existing message-ID format, which only allows space for six characters – enough for a pid/tid in base-62 but not enough for a GUID.

    (The original gets around the ID recycling problem by including a timestamp as well, so process IDs don’t have to be unique across time, only unique across the system at the moment at which the message-ID’s created. The Win32 thread ID’s unique across the system at any given moment, right?)

    Of course, now I’ve just read that AppDomain.GetCurrentThreadId is deprecated in Whidbey anyway…

  10. AppDomain.GetCurrentThreadId is deprecated, for the reason discussed in this blog. There is a replacement Thread.GetManagedThreadId, which simply calls Thread.GetHashCode().

    For the original problem, you can have a global ID stored in the machine(like in a well known file, or registry), each thread reads the ID, increments it, then store it back. Of course you need some synchronization. This should be able to ensure the uniqueness of the ID.

    Another alternative is create a GUID, then hash it to the six character space, and hope it won’t collide.