Threads and Synchronization

Perhaps the most interesting new capability of Win32 is its ability to create new threads of execution and to synchronize operations among them. In the long run, this will be the way to make operations run independently and interact smoothly. But don’t expect multithreading to solve all your problems in this version.

Visual Basic itself doesn’t use threads in critical areas. For example, the next time you print a Visual Basic project, notice how the Print dialog box works. You specify what you want to print, click on OK, and then watch a print message box until the print job is finished. You can’t edit or do anything else in the
IDE until your document has been shipped off to the printer. In a multithreaded print implementation, you wouldn’t have to wait. The print thread would
be launched independently, and you could do other chores while it worked in the background.

Of course, background operations can be implemented in other ways. Many
16-bit programs have had background printing for years, but it wasn’t always smooth and clean. I haven’t tried it, but I imagine that you could implement background printing by launching a modeless form that handles the printing. The form would have a timer that periodically calls timer events to do chunks of the print job. But this technique depends on your ability to break the background task into chunks. A multithreaded implementation lets the operating system break the job into chunks.

Visual Basic provides an automatic form of multithreading, but it only works in limited situations. You can create a multithreaded ActiveX EXE component by specifying Unattended Execution on the General tab of the Project Properties dialog box. That means it can’t have a user interface. The Visual Basic documentation describes in detail the multithreading arrangement used for such servers. The File Notification Server described in the next section will be this kind of component, but I won’t have much to say about the multithreading part because it works automatically.

Visual Basic ActiveX DLL components can cooperate with multithreaded clients as long as they are marked for Unattended Execution. There are two kinds of multithreaded programs that might call such a DLL: the ActiveX EXE components mentioned above, and programs written in other languages. In particular, two new Microsoft technologies, Internet Information Server (IIS) and the Microsoft Transaction Server (MTS), expect any components they work with to be multithread-capable. That’s why, late in the development of this book, I had to rip all the classes with user interfaces out of VBCore and put them in a separate VisualCore component. VBCore is marked for Unattended Execution; VisualCore is not. That means that VBCore has no forms and no calls to MsgBox or InputBox. When a thread from a multithreaded client calls, VBCore is guaranteed not to block calls from the client’s other threads. If one thread calls SortArray with 100,000 items, the next thread won’t have to wait for the sort
to finish.

I’ll leave you to explore the full implications of multithreaded EXE servers and thread-safe DLLs. The important thing for this discussion is that the Visual Basic library has to be at least partially thread-safe to support these technologies. And if the library can work with Visual Basic’s automatic multithreading, what’s to stop it from working with not so automatic multithreading?

As a hardcore programmer, you’re undoubtedly saying, “If there’s an API to launch threads, I’m sure I could call it.” Indeed, there is a CreateThread function, and with the AddressOf operator, it’s easy to use it to send threads off to do their appointed tasks. Whether they’ll ever come back is another matter. But what the heck. Crashing only hurts for an instant.