The single nastiest bug I've ever seen was a multithreading problem. By the time I finally fixed it, over 3 whole weeks had elapsed. Now, that particular bug was an extreme case, and most multithreading issues aren't quite so bad. But the fact remains that multithreaded development is not for the timid. Debugging those programs is just plain hard, and if you're on a tight schedule, then you might want to consider avoiding the entire issue by designing your program in a single-threaded fashion or with only minimal thread support. Used properly, multithreading can provide huge benefits. But be prepared to pay for those benefits with drastically increased debugging time.
.NET makes it much easier to write multithreaded code than ever before. Visual Basic 6 didn't support multiple threads at all, and even in Visual C++ 6, the threading API was quirky. .NET languages, on the other hand, have access to a well-designed, object-oriented thread library, and anyone can quickly begin writing multithreaded .NET programs. But debugging those programs is a different story. Unfortunately, debugging multithreaded programs in .NET is just as hard as it was in classic Win32. But debugging them is possible—you just need to know the right techniques.
This chapter assumes you're already at least vaguely familiar with what a thread is and why someone might want to use more than one of them. We'll start with a brief review, but if you're completely new to the idea of multiple threads, be warned that this chapter is aimed at explaining how to debug thread problems rather than serving as a tutorial for every method in the thread API. After a review of threading, we'll discuss the most common sources of thread errors: deadlocks, race conditions, and starvation. Finally, we'll finish with a few stories about some real-world threading bugs and some strategies for dealing with them.