Search code examples
c#clrpinvoke

How do I force the CLR to exhibit OS thread switching?


Related to these questions:

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

How often does a managed thread switch OS threads?

I would like to be able to actually test the Thread.BeginThreadAffinity() methods and verify how they work and that they work.

Is there some .NET functionality that will force an OS thread switch?


Solution

  • There is not much to test with Thread.BeginThreadAffinity(). I calls a function in the CLR host, IHostTaskManager::BeginThreadAffinity(). IHostTaskManager is an optional interface that a custom CLR host can implement to provide a custom thread implementation, one that doesn't necessarily use an operating system thread. The ICLRTaskManager and ICLRTask interfaces provide the core services for such a custom thread.

    These interfaces were added in .NET 2.0, on request by the SQL Server team. SQL Server has had a custom threading option built in for a long time, based on fibers. Fibers were popular in the olden days when machines with multiple processor cores were still rare. Other names for a fiber are "green thread" and "co-routine". They've been put to pasture by the multi-core revolution in the previous decade.

    The SQL Server project was a bust. They could not get it reliable enough and abandoned the project. Unfortunately we are left with the consequences, there is no simple way to map a .NET thread to an OS thread, the subject of your first link. As well as the considerable FUD shown in the accepted answer.

    While the CLR still has the basic support for this feature, I do not know of a single example where a custom host implements its own threading. The massive failure of the SQL Server team project certainly was a major signpost that this is difficult to implement, considering the resources the team had access to to make this work. And it just doesn't make sense in general, mapping a single thread to a single processor core, as done by the operating system by default and used by the default CLR host, is incredibly hard to beat for efficiency. Processor cores are very cheap to buy these days.

    Long story short: Thread.BeginThreadAffinity() does nothing. CLR threads are already affine to OS threads by default. The odds that you'll ever run into a custom CLR host where it does anything at all are sufficiently close to zero to ignore the method.

    A simple way to invoke an OS thread context switch is by using one of the WaitHandle.WaitXxx() methods or Thread.Sleep() with a non-zero wait.