How do I get the current thread id without AppDomain.GetCurrentThreadId () so that it actually works?

Since AppDomin.GetCurrentThreadId () is deprecated

"AppDomain.GetCurrentThreadId is deprecated because it does not provide a stable ID when managed threads are running on fibers (aka light threads). To get a stable ID for a managed thread, use the ManagedThreadId property in Thread. Http://go.microsoft.com/fwlink /? linkid = 14202 "

I tried not to use it. However, the explanation that "Thread.CurrentThread.ManagedThreadId" will work is useless because it does not contain the Win32 thread ID that I need for Win32 calls. So I implemented it myself as follows.

public sealed class AppDomainExtender
{
    public static int GetCurrentThreadId_New()
    {
        return Process.GetCurrentProcess().Threads.OfType<ProcessThread>().SingleOrDefault(x => x.ThreadState == System.Diagnostics.ThreadState.Running).Id;
    }
}

      

Now there are two problems.

  • If that works, won't it do the same as AppDomain.GetCurrentThreadId?
  • This does not work for the reason that the current thread may change when the SingleOrDefault loop loops. This behavior is weird, but it just threw an InvalidOperationException ("The sequence contains more than one element"). This appears to be the case, for example, when using multiple desktops (I assume this is only possible by copying a thread that runs a loop with a different ID).

Questions:

  • Is AppDomain.GetCurrentThreadId falsely declared deprecated?
  • How can I make the expression "Process.GetCurrentProcess (). Threads.OfType (). SingleOrDefault (x => x.ThreadState == System.Diagnostics.ThreadState.Running) .Id" atomic, or is it even possible?
+3


source to share


1 answer


The downside to AppDomain.GetCurrentThreadId () is an inconvenient truth, certainly not a "false" declaration. Starting with .NET 2.0, communication between the .NET thread and the operating system thread has been broken. A custom CLR host can implement threads as it sees fit by implementing the IClrTask interface . Or, in other words, you have no guarantee that two different .NET threads are using different operating system threads with different thread IDs.

It was, in general, popular in the 1990s and early 2000s, going by names like "light streams", co-routines, fibers, "green streams", etc. The idea was to avoid thread context switching the operating system and switching CPU registers in software instead. SQL Server was the main beneficiary of this feature and has built-in support for "fiber mode".

While the SQL Server team received this feature, they ultimately decided not to ship it. They abandoned the project when they could not get it stable enough. The problem that probably inspired this article , published in the same year, that their project was about to happen. This has not been repeated. Not least because this feature has been overshadowed by a multi-core coup. The cost of the context switch in modern cores is dominated by the state of the CPU caches; it is impossible to compete with each core that has its own L1 and L2 caches.



I don't know which CLR host is actually implementing IClrTask, SQL Server command failure was definitely a big red flag. However, this does not rule out the possibility that a script you can think of is running your code in the context of a large unmanaged application that supports scripting in a managed language. A typical example of this would be a CAD program.

You would be dead in the water in the very unlikely event that your code would actually work in this context, so set your laser to stun and move forward. Aside from having to live with the deprecation warning, the most reliable workaround is to push GetCurrentThreadId () . It's very fast.

+10


source







All Articles