Additional Observations

Debugging a multithreaded application is harder than debugging a single-threaded application because of the synchronization issues and interactions. An advantage of CMultiThread is that its basic threading functionality has already been debugged by me, so you can derive from it and only have to debug the DoWork method. Alternatively, if you choose to develop your own base class using a similar approach, you only have to debug the threading functionality once. Reuse of the class is easy, as you've seen.

Performance tuning your threads by varying the intervals at which they're unblocked is straightforward. You can either call the CMultiThread constructor with a different interval parameter, or call CMultiThread::SetCycleTime to accomplish this. You also might find it advantageous to change a thread's priority while it's running. SetThreadPriority can take a number of values provided by constants in the Visual C++ header file winbase.h, ranging from THREAD_PRIORITY_TIME_CRITICAL down to THREAD_PRIORITY_IDLE.

CMultiThread is a class with a single embedded thread. There are several ways to extend this concept to create classes containing multiple embedded threads. This might be desirable if, for example, you want to query multiple Internet sites concurrently. The simplest way to accomplish this is to create a duplicate of CMultiThread called CMultiThread2 with an overrideable method called DoWork2. Your new class can then inherit from both CMultiThread and CMultiThread2. You can repeat this as many times as you want, as long as each class has a different DoWork signature. Admittedly, this method is not elegant, but it works and is simple.

Another method for creating such a class is to modify CMultiThread to provide additional embedded threads. This modified class, though, would have to do housekeeping for each of its threads and would need to call DoWork with a thread ID as a parameter. This would result in a significantly more complicated class.

As you've seen, multithreading is a useful tool in many applications. When you're developing such an application with an object-oriented approach, it's often useful to embed multithreading in the objects that require it. Once you've developed and debugged a multithreaded base class like CMultiThread, you can use it for any number of derived classes with ease and safety

To obtain complete source code listings, see page 5.