.NET Threading and Tasks

Since creating and destroying threads is a costly set of operations, the CLR manages its own thread pool. There is one CLR thread pool per CLR. So if there is multiple versions of the CLR loaded in a process there are multiple CLR thread pools.

Initially there are no threads in this thread pool. As you create threads, those threads become part of the CLR thread pool. When the thread finishes, the thread is not destroyed. It becomes part of the CLR thread pool. Ready to perform some more work as needed.

You use the System.Threading.ThreadPool’s static function QueueUserWorkItem in order to execute work on a CLR thread pool thread. See following example:

…
ThreadPool.QueueUserWorkItem(DoSomething,3000);
…
private static void DoSomething(object state)
{
Console.WriteLine(“Work Starting!”);
// do work
Console.WriteLine(“Work Done!”);
}

The QueueUserWorkItem call works as expected. However you have no way of knowing when the worker function is finished. Nor are you able to get some kind of return value from the worker function. In order to fix these issues and more, Microsoft came up with Tasks; located in namespace System.Threading.Tasks. The previous code could now look like:

…
new Task(DoSomething, 3000).Start();  // Way 1
// or
Task.Run( () => DoSomething(3000) );  // Way 2
…

In order to get a return value, you could do something like this:

…
var result = Task.Run( () => GetAge(1001) );
result.Wait(); // Waits until task is completed
Console.WriteLine($”Age was: {result.Result});
…
private static int GetAge( long id )
{
    return 45;
}

There is also the System.Threading.Thread object. This is a so called soft-thread object. It is what the CLR deals with. But it has an underlying hard-thread object. Which is the thread the underlying OS deals with. The previous code example would look something like this:

…
var threadObject = new System.Threading.Thread( new ParameterizedThreadStart( GetAge ) );
threadObject.Start( 1001 );
threadObject.Join( );
…

It is recommended that you only use the System.Threading.Thread object for threads that run continuously throughout your applications lifetime. Tasks should be used in mostly all other cases.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: