This recipe will show how a thread pool works with many asynchronous operations, and how it is different from creating many separate threads. Learn how a thread pool works with many asynchronous operations and how it is different from creating many separate threads.
using System;
using System.Diagnostics;
using System.Threading;
//
// Thread Pool and the Degree of Parallelism
//
// This recipe will show how a thread pool works with many asynchronous operations,
// and how it is different from creating many separate threads. Learn how a thread
// pool works with many asynchronous operations and how it is different from
// creating many separate threads.
//
// How It Works...
//
// When the main program starts, we create many different threads and run an
// operation on each one of them. This operation prints out a thread ID and
// blocks a thread for 100 milliseconds. As a result, we create 500 threads,
// which run all of those operations in parallel. The total time on my machine
// is about 300 milliseconds, but we consume many operating system resources for
// all those threads.
//
// Then, we follow the same procedure, but instead of creating a thread for each
// operation, we post them on a thread pool. After this, the thread pool starts
// to serve these operations; it begins to create more threads near the end, but
// still, it takes much more time, about 12 seconds on my machine. We save
// memory and threads for an operating system usage but pay with an execution
// time for it.
//
namespace Chapter3.Recipe3
{
class Program
{
static void Main(string[] args)
{
const int numberOfOperations = 500;
var sw = new Stopwatch();
sw.Start();
UseThreads(numberOfOperations);
sw.Stop();
Console.WriteLine("Execution time using threads: {0}", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
UseThreadPool(numberOfOperations);
sw.Stop();
Console.WriteLine("Execution time using threads: {0}", sw.ElapsedMilliseconds);
}
static void UseThreads(int numberOfOperations)
{
using (var countdown = new CountdownEvent(numberOfOperations))
{
Console.WriteLine("Scheduling work by creating threads");
for (int i = 0; i < numberOfOperations; i++)
{
var thread = new Thread(() =>
{
Console.Write("{0},", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(0.1));
countdown.Signal();
});
thread.Start();
}
countdown.Wait();
Console.WriteLine();
}
}
static void UseThreadPool(int numberOfOperations)
{
using (var countdown = new CountdownEvent(numberOfOperations))
{
Console.WriteLine("Starting work on a threadpool");
for (int i = 0; i < numberOfOperations; i++)
{
ThreadPool.QueueUserWorkItem( _ =>
{
Console.Write("{0},", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(0.1));
countdown.Signal();
});
}
countdown.Wait();
Console.WriteLine();
}
}
}
}