Introduction to Multithreading in C#
This article is a very basic introductory tutorial for using multiple threads in C#. I’ll explain what threads are, why you would want to use them, and how to use them. I’ll also show you several examples for creating threads, killing threads, etc.
What’s a Thread?
A computer program is generally very linear. That is, you have a sequence of instructions that get executed one after another in an orderly and predictable fashion. This scenario only affords you one path of execution. Threads allow you to execute multiple paths of code simultaneously. Now, simultaneously in this case does not necessarily mean physically at the same time. Both your operating system and processor must support this for that to be true. Threads are not particular to C#; most modern programming languages such as Visual Basic.Net support the concept of threads.
So Why Do I Need Multiple Threads?
Threading is handy because many programming tasks are asynchronous. That is, I can start the task and go on about my business and when that task is finished it can let me know and I can take action. An example of this would be downloading files from a remote location. I can start downloading three files and when the first is finished I can process it while the others continue to download.
There are numerous other reasons. Consider for instance a long task like sorting a million numbers. If I start that task on the thread that runs the GUI then I couldn’t update my user interface which means I couldn’t respond to user requests like button clicks.
Ok, lets move on to an example of creating a new thread via C#.
Creating a Thread with C#
Creating a thread is easy; we make use of the Thread object from the System.Threading namespace. When we create the thread we must pass it a ParameterizedThreadStart or ThreadStart delegate. This will be the method that gets invoked on the new thread – it’s the starting point. New threads begin life in a stopped state. To make it run we call the Thread.Start method.
Thread myThread = new Thread(MyThreadFunction); myThread.Start(); private void MyThreadFunction() { MessageBox.Show("HI"); }
Congratulations, you’ve created your first thread that runs in parallel with your main thread.
Passing an Argument to the New Thread
You can easily pass an argument to the thread like so:
Thread myThread = new Thread(MyThreadFunction); myThread.Start("HELLO WORLD"); private void MyThreadFunction(object x) { MessageBox.Show(x as string); }
Keep in mind that this is not the best way to pass data to the thread. Since Thread.Start accepts only an object this is not very type safe. Image if we didn’t pass a string or the object didn’t have a ToString method. The best way to accomplish this would be to encapsulate your thread function in a class with data members you could set ahead of time.
Waiting for a Thread to Stop
Now that we have our thread up and running, we may at some point wish to wait for it to complete. This is accomplished with the Thread.Join method. Here is an example for Thread.Join:
myThread = new Thread(MyThreadFunction); myThread.Start("HELLO WORLD"); myThread.Join(); MessageBox.Show("ALL DONE!"); //-elsewhere private void MyThreadFunction(object x) { MessageBox.Show(x as string); }
When the first piece of code executes it will create a new thread that will begin running in MyThreadFunction. After calling myThread.join that thread will go to sleep and stop executing until MyThreadFunction returns. This will happen after you dismiss the message box. Finally, when MyThreadFunction exits and the thread is destroyed, the original thread will continue execution at the next statement and pop its message box.
One thing to watch out for is what happens if the thread function never returns meaning the thread never dies. In this situation you can specify a timeout value in Thread.Join. The method will block for a predetermined amount of time waiting for the thread to terminate. If the thread did not terminate then Thread.Join would return false.
Stopping a Thread
Stopping a thread is simple. You call Thread.Abort on the thread you wish to stop.
myThread.Abort();
This will cause a ThreadAbortException to be raised on the thread you are trying to stop. Now this usually stops the thread. It’s possible that the thread can abort your abort and continue living. There are a few other circumstances that can prevent the thread from aborting.
Sharing Variables
When you have two or more threading running it’s possible that they could be executing at the same time. This can create problems when both threads are trying to read/write to the same variable. You have to synchronize thread access to shared variables. There are many synchronization primitives available to you in C# via the .Net Framework Library such as AutoResetEvent, Monitor, and Mutex. This is a big subject so I will defer it till another post.
Along those same lines here’s a tip: If you create secondary threads they cannot modify controls on your GUI. Only the thread that created a control can modify its properties. You will generate the dreaded illegal cross thread exception. I’ve already posted a brief work around for this problem
So that’s it for my C# threading tutorial. Now you know the basics of how to create a thread, how to kill a thread, how to wait for a thread, and some general threading principles. This is a big subject and I’ve hardly done it justice with this little bit of writing. If there are sufficient interests, I will elaborate on some more advance multithreading techniques that are applicable in all .Net languages – not just C#. I’ll leave you with a small incomplete pro and con list about using multiple threads.
Advantages of Multithreading
- Improved performance – Multiple threads can execute concurrently.
- Streamline application logic – Some tasks are easier to conceptualize this way
- Improves responsiveness of an application – GUI still works under heavy load.
Disadvantages of Multithreading
- Hard to write and debug – Nuff said!!
- Performance impact from synchronizing access to shared variables
- There is a limit to how many threads an operating system can handle efficiently
- Context switching between threads can hurt performance
April 8, 2009
Posted in: C#, Programming

2 Responses
Hi, good post. I have been wondering about this issue,so thanks for posting. I’ll definitely be coming back to your site.
Hi people
I’m new here
Thanx
Leave a Reply