GetCurrentThreadId() has been deprecated, and MSDN states ManagedThreadId replaces it.
However, I'm getting different results, and the latter causes an exception in my code. My code is adapted from this post.
public static void SetThreadProcessorAffinity(params byte[] cpus)
{
if (cpus == null)
{
throw new ArgumentNullException("cpus");
}
if (cpus.Length == 0)
{
throw new ArgumentException(@"You must specify at least one CPU.", "cpus");
}
// Supports up to 64 processors
long cpuMask = 0;
byte max = (byte)Math.Min(Environment.ProcessorCount, 64);
foreach (byte cpu in cpus)
{
if (cpu >= max)
{
throw new ArgumentException(@"Invalid CPU number.");
}
cpuMask |= 1L << cpu;
}
// Ensure managed thread is linked to OS thread; does nothing on default host in current .NET versions
Thread.BeginThreadAffinity();
#pragma warning disable 618
// The call to BeginThreadAffinity guarantees stable results for GetCurrentThreadId,
// so we ignore the obsolete warning.
int osThreadId = AppDomain.GetCurrentThreadId();
osThreadId = Thread.CurrentThread.ManagedThreadId;// NOT THE SAME VALUE
#pragma warning restore 618
// Find the ProcessThread for this thread
ProcessThread thread = Process.GetCurrentProcess().Threads.Cast<ProcessThread>()
.Where(t => t.Id == osThreadId).Single();
// Set the thread's processor affinity
thread.ProcessorAffinity = new IntPtr(cpuMask);
}
I can see the issue is one gets the thread's process ID while the other gets the app's process ID.
How do I get this to work without using the deprecated method? The original Stack Overflow article states to use P/Invoke, but I don't know how, and that isn't what MSDN states.
No, ManagedThreadId has no relationship at all with the operating system's thread ID. The CLR simply numbers threads, starting at 1. This is a fairly tragic side-effect of a project in the SQL Server group that tried to emulate .NET threads with fibers. The project was abandoned, they could not get it stable enough. Sadly the thread ID mapping was left the way it was when .NET 2.0 shipped. Technically the feature is still available for custom CLR hosts to implement threads the way they want, I'm not aware of any mainstream implementation actually doing so. The SQL Server group failure is a giant red flag.
The only way to bypass the obsoletion warning is to pinvoke GetCurrentThreadId(). The link takes you to do correct pinvoke declaration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With