A beginner's guide to threading in C#
Published: 31 May 2002 21:34 BST

This article begins a series on the tools and techniques involved in threading. I'll start with an introduction to the concept and a survey of some of the more common constructs and how to use them.
The yin and yang of threading
It's been said that one of the best things about Java is that it makes threading easy, but -- at the same time -- that one of theworstthings about Java is that it makes threading easy. When Microsoft developed C#, they brought this ease-of-use dilemma to a whole new platform. There are more primitives to play with in C# than in Java, but the basic Java primitives of the Thread object and synchronisation monitors are there in similar form and function and provide more than enough steel to hoist yourself on your own petard. So be very, very careful in making the decision to utilize explicit multithreading in your application.
Why not to multithread
The first point to remember when deciding whether to avoid multithreading is that, unless you are doing weekend play-coding, do not use threading simply because it is cool. It gets hot soon enough, and if you're not careful, your boss will, too. Second, you should not use multithreading to make things faster until you have proven to yourself (and hopefully a few others around you) that a single threaded implementation is unacceptably slow. And finally, before venturing into an explicitly multithreaded mechanism, remember that Microsoft provides an apartment model that allows an object, written as a single-threaded construct, to run in a multithreaded environment. So you may not need to explicitly code for multithreading. The apartment model is a subject for another article.
If not done properly, multithreading opens a Pandora's box of ill effects. With no apparent repeatability, values can turn to utter garbage. Counters can fail to increment. Your application can suddenly freeze. Resources such as database connections can unexpectedly close or become exhausted. Some of the most challenging puzzles in a senior developer's career arise from sleuthing a threading issue. The big problem is that these puzzles usually take time to solve, which can have a serious effect on product delivery dates, or worse, on product reliability.
Why to multithread
You may have a good candidate for multithreading if your application has operations like any of the following:
- In series, can take an unacceptably long time to complete
- Can be made parallel
- May spend an appreciable amount of their execution time waiting for network, file system, or user or other I/O response
If your code is fast enough, but you think you could make it really fast (you do have performance specifications, don't you?), resist the urge. If you aren't sure that you can make your operations parallel (such as performing simultaneous database updates into the same table, when your database does table-level locking), fight the temptation. If you don't know whether your application is spending a lot of time waiting for input or output to complete, determine that first. Three threads, each performing a computation of pi to the millionth place, will actually take longer to complete than repeating the computation three times in the same thread. This scenario fails the third criterion above -- there are no idle cycles during one computation that a second parallel computation might be able to use.
The one exception to this rule is that if you are writing for a multiprocessor machine, you might stand to gain by making suitable operations parallel, even if each of the operations is a CPU hog.












