Click here to Skip to main content
15,867,594 members
Articles / Programming Languages / C#

Threading with the Thread Pool and BackgroundWorker

Rate me:
Please Sign up or sign in to vote.
4.25/5 (4 votes)
25 Feb 2010CPOL2 min read 31.3K   8   4
Today I want to talk about threads since every programmer works with them and absolutely loves them.

Today I want to talk about threads since every programmer works with them and absolutely loves them. Typically, when we create a thread, your code can look like this:

C#
static void Main(string[] args)
{
TraditionalThreadCreation();
Console.Read();
}

static void TraditionalThreadCreation()
{
     // Create threads
Thread thread1 = new Thread(Task);
Thread thread2 = new Thread(Task);

// this guy will do even numbers
thread1.Start(0);
// this guy will do odd numbers
thread2.Start(1);
//wait for first thread to finish
thread2.Join();
}

static void Task(object p)
{
for (int i = int.Parse(p.ToString()); i <=10; i += 2)
Console.WriteLine(i);
}

There is nothing wrong with creating threads like the code above. But there is one thing you have to keep in mind. Thread creation and startup has overhead. A typical thread can take up 1MB of your precious memory. Shocked?? Well, you are not alone.

To mitigate this overhead, the .NET Framework has given you the thread pool (No, this is not a swimming pool for threads). Basically, these are pre-created threads that are shared and recycled. They save you the trouble you have creating threads but most importantly they alleviate the overhead in creating a thread.

Thread Pool - Things you should know:

  • They run in the background.
  • They are limited and when you’ve used them up; your tasks will begin to queue up.
  • The Thread Pool only runs a certain amount of threads simultaneously. This is done to not choke your CPU.  

How Can You Use the Thread Pool You Ask?

Well, that is done in a few ways. But for now, I will list 2 that are pre .NET Framework 4.0:

  1. ThreadPool.QueueUserWorkItem
  2. BackgroundWorker

Thread Pool

This is very easy to use. Here is how.

C#
static void Main(string[] args)
{
 ThreadPool.QueueUserWorkItem(Task, 1);
}

static void Task(object p)
{
 for (int i = int.Parse(p.ToString()); i <=10; i += 2)
 Console.WriteLine(i);
}

Now how much faster is the Thread Pool vs Traditional Thread execution? Well, it depends. Remember that your task may become queued if the limit on Thread Pool has been reached or the total number of simultaneous threads have been met.

Just for kicks, I tried just starting and executing s single thread traditionally and via the thread pool and on average, the thread pool was 200% faster.

C#
class Program
 {
 static void Main(string[] args)
 {
 TraditionalThreadCreation();
 //Wait for the guy above to finish
 Thread.Sleep(1000);
 ThreadPoolThreadCreation();

 Console.Read();
 }

 private static void ThreadPoolThreadCreation()
 {
 var start = DateTime.Now;
 // this guy will do even numbers
 ThreadPool.QueueUserWorkItem(Task, new object[] 
	{start, "ThreadPoolThreadCreation() Finished: {0}" });
 }

 private static void TraditionalThreadCreation()
 {
 var start = DateTime.Now;
 Thread thread = new Thread(Task);

 thread.Start(new object[] {start,"TraditionalThreadCreation() Finished: {0}" });
 }

 private static void Task(object p)
 {
 var start = (DateTime)((object[])p)[0];
 var end = DateTime.Now;
 var message = ((object[])p)[1].ToString();

 //I only care about starting up and running executing and not 
 //the time the task takes to execute
 Console.WriteLine(message, end - start);

 for (int i = 0; i <= 10; i += 2)
 Console.Write(i);

 Console.WriteLine();
 }
 }

Background Worker

This guy is in the System.ComponentModel namespace. It is used primarily in GUI development where you execute a task on background thread and periodically update GUI elements on the foreground thread in the form of progress reporting. To use BackgroundWorker, you have to do a few things.

  1. Instantiate
  2. Handle the DoWork Event
  3. Call RunWorkerAsync
C#
class Program
{
private static BackgroundWorker _theBGW = new BackgroundWorker();

static void Main(string[] args)
{
   BackgroundWorkerRun();
   Console.Read();
}

static void BackgroundWorkerRun()
{
_theBGW.DoWork += new DoWorkEventHandler(bw_DoWork);
_theBGW.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
_theBGW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
//This must be set to true in order to be able to cancel the worker
_theBGW.WorkerSupportsCancellation = true;
//This must be set to true in order to report progress
_theBGW.WorkerReportsProgress = true;
_theBGW.RunWorkerAsync();
Thread.Sleep(1000);
//uncomment this line to cancel before percentage reaches 100
//if (_theBGW.IsBusy)
// _theBGW.CancelAsync();
}

static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(!e.Cancelled)
Console.WriteLine("Worker Done!! - {0}", e.Result);
else
Console.WriteLine("The answer to the universe will remain unknown");
}

static void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Completed {0}%", e.ProgressPercentage);
}

static void bw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 10; i <= 100; i += 10)
{
if (!_theBGW.CancellationPending)
{
_theBGW.ReportProgress(i);
Thread.Sleep(1000);
}
else
{
e.Cancel = true;
return;
}
}
e.Result = "The secret to the universe is 42";
}
}

In my next post, I will talk about the TPL (Task Parallel Library) in .NET Framework 4.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) 4CoreDev
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionNice Article Pin
Saineshwar Bageri4-Dec-17 21:06
Saineshwar Bageri4-Dec-17 21:06 
Nice Article

QuestionNice Pin
Ivandro Ismael7-Jul-15 20:03
Ivandro Ismael7-Jul-15 20:03 
GeneralMy Vote of 4 Pin
JoltyTaku8-Aug-14 3:55
JoltyTaku8-Aug-14 3:55 
GeneralMy vote of 3 Pin
kunal sen gupta9-Jul-14 0:32
kunal sen gupta9-Jul-14 0:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.