| it can call a method on the object which will raise an event in the client. By keeping the number of method calls small relative to the amount of work being done in the background function, you can achieve very effective results.
What if you want to perform a background operation that does not need to use an object? Obviously, the problems with the COM threading contract vanish. But other problems appear. How will the background thread signal completion to the foreground thread? How will they exchange data? How will the two threads be synchronized? All of these things are possible with appropriate use of API calls. Refer to my Visual Basic 5.0 Programmer''''s Guide to the Win32 API for information on synchronization objects such as Events, Mutexes, Semaphores and Waitable Timers.
It also includes examples of memory mapped files which can be helpful in exchanging data between processes. You may be able to use global variables to exchange data as well -- but be aware that this behavior is not guaranteed by Visual Basic (in other words, even if it works now, there is no assurance that it will work in the future). I would encourage you to use API based techniques to exchange data in this case. However, the advantage of the object based approach shown here is that it makes the problem of exchanging data between threads trivial -- simply do it through the object.
Conclusion #1
I once heard from an experienced Windows programmer that OLE is the hardest technology he''''s ever needed to learn. I agree. It is a vast subject and parts of it are very difficult to understand. Visual Basic, as always, hides much of the complexity from you.
There is a strong temptation to take advantage of advanced techniques such as multithreading using a "tips and techniques" approach. This temptation is encouraged by articles that sometimes present a particular solution, inviting you to cut and past their techniques into your own applications.
When I wrote my original Visual Basic Programmer''''s Guide to the Windows API, I explicitly disavowed that approach. I felt that it is generally irresponsible to include code in an application that you don''''t understand, and that real knowledge, while hard to gain, is worth the effort even in the short run.
Thus my API books were designed not to provide quick answers and easy solutions, but to teach API usage to such a degree that programmers can intelligently apply even the most advanced techniques correctly, quickly going beyond what is shown in the book. I applied this same approach to my book on Developing ActiveX Components, which spends a great deal of time discussing the principles of ActiveX, COM and object oriented programming before getting into implementation details.
Much of my career in the Visual Basic field, and much of Desaware''''s business, has been based on teaching Visual Basic programmers advanced techniques. The reader who inspired this article by criticizing me of holding back on threading technology and thus betraying this principle missed the point.
Yes, I teach and demonstrate advanced techniques -- but I try never to miss the bigger picture. The advanced techniques that I teach must be consistent with the rules and specifications of Windows. They must be as safe to use as possible. They must be supportable in the long run. They must not break when Windows or Visual Basic changes.
I can claim only partial success -- it''''s a hard line to draw sometimes, and Microsoft is at liberty to change the rules whenever they wish. But I always keep it in mind and try to warn people where I think I may be pushing the limit.
I hope this multithreading discussion shown here demonstrates the dangers of applying "simple techniques" without a good understanding of the underlying technology.
I can''''t promise that the apartment model version of CreateThread usage is absolutely correct -- only that it is safe to the best of my understanding and testing.
There may be other factors that I have missed -- OLE is indeed complex and both the OLE DLLs and Visual Basic itself keep changing. I can only say that to the best of my knowledge, the code I''''ve shown does obey the COM rules and that empirical evidence shows that Visual Basic 5.0''''s runtime is sufficiently thread safe to run background thread code in a standard module.
Sequel #1- Regarding VB6
The following comments were written after the release of VB6
Sigh... It seems that many readers missed my original point. The ideas was not to encourage VB programmers to use CreateThread with Visual Basic. It was to explain clearly and accurately why you shouldn''''t use CreateThread with Visual Basic.
So, when Visual Basic 6 turned out to be considerably less thread-safe than VB5, breaking the sample programs referenced by this article, what could I do? I suppose I could go back and revise the samples and try to make them work with VB6. But then the same problem might arise with later versions of Visual Basic as well.
Visual Basic offers good support of multithreading including multithreaded clients in ActiveX servers (this is described quite thoroughly in the latest edition of my Developing COM/ActiveX components book). I strongly encourage you to stay within the rules defined by the Visual Basic documentation and not use the CreateThread API with Visual Basic.
For those who insist on pursuing CreateThread further, to start with you should eliminate all Declare statements and use a type library instead. I don''''t promise that this will fix the problem, but my initial testing indicates that it is a necessary first step.
Sequel #2 - Regarding SpyWorks 6.2
April 2000...
It seems that telling people not to use CreateThread wasn''''t a satisfactory answer after all. I continued to receive requests for information on how to create threads both for background operations and to use NT synchronization objects from VB DLL''''s. As you probably know, when enough people ask for something that isn''''t easy or possible to do with Visual Basic, sooner or later it shows up as a new feature in SpyWorks. With version 6.2, we''''ve included a component called dwBackThread that allows you to create objects from your VB DLL in their own thread and then trigger background operations. The component handles all of the necessary marshaling and cleanup for you so that it''''s as safe as one can be when doing multithreading. Most important - it follows all of the COM threading rules, so you don''''t have to worry about pieces of VB or components you use suddenly failing to work. See our product pages on SpyWorks for further details.
For further reference:
"Dan Appleman''''s Developing COM/ActiveX Components with Visual Basic 6.0: A Guide to the Perplexed" published by SAMS, ISBN 1-56276-576-0.
"Dan Appleman''''s Visual Basic 6.0 Programmer''''s Guide to the Win32 API" published by SAMS, ISBN 0-672-31590-4.
Desaware''''s web site at www.desaware.com.
上一页 [1] [2] [3] [4] [5] [6] [7] |