|
|
|
Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. |
Multithreading
Multithreading in VB - Where the waters become murky....
Multithreading, as far as VB is concerned, is very difficult to implement.
Though VB supports multithreading, it basically supports it only for ActiveX
EXEs and to some extent in ActiveX Dlls (The ActiveX Dlls basically allow very
primitive multithreading - It just maps instances of itself onto client threads
that request its services. If your client is single threaded, the DLL too does
not multithread !)
Sometime back I had demonstrated a method of multithreading using ActiveX
EXEs. Though it is very stable, the trouble is the code tends to be very cumbersome...
So I have designed a new generic multithreader, that, though not as stable as
multithreaded ActiveX EXEs, is sufficient for most uses...
A Bit of history....
Soon after I demonstrated how to multithread using ActiveX EXEs, I realized
that though the technique was useful, and though most of you appreciated it, it
tended to be somewhat cumbersome and then I began to think of ways of creating
multiple threads using other methods.... Soon afterwards, I came across an
article written by an extremely talented and innovative programmer, Matt
Currland (who is unfortunately not a member of PSC), where he demonstrated how
to use CreateThread() safely with VB.. But the problem was, the example was
very complicated and difficult to understand owing to the many class modules it
used and the zigzag nature of execution... After hours or effort, punctuated
by crashes, freezes and quite a few reboots, using some inspiration from his
article I have created MThreadVB. Though it may not be as "technically
right" as his code, I had to sacrifice some of the correctness for ease of
use and the generic architecture.... (Which his code sadly did not provide - His
was basically a demo program)
Some Technical Stuff ....
How does the multithreader work ?! You might ask - Here's the
answer !
Normally, all VB programs are heavily dependent on the runtime DLL for its functioning.In VB 6, within the multithreaded
function (Called By the CreateThread() API once the thread has been created) , any calls
to the runtime DLL fails (due to some reason perhaps which only the Microsoft VB
team might know !) causing your program to crash immediately....
Even an API call is not really compiled in "real" native code in VB and is interpreted by the runtime DLL...
An API call too thus ultimately involves calling the runtime DLL,that causes VB to
crash.
Those of you who do not believe this can do a simple test - Open the API
viewer, select the mciExecute API defied in the Win32API.txt file... Place it in
a project and compile it.... Even though this API is a part of WinMM.Dll, you
will find no reference to the WinMM.Dll in case you view the executable in the
Depencency Viewer (since the code referencing the DLL is not placed
"explicitly" in the executable. When you call the API, the actual call
to WinMM.Dll is ultimately made by the runtime DLL only) .... But if you were to
open the EXE in MS-DOS editor, you can see the text strings "winmm.dll"
and "mciExecute" !
Most standard VB statements and functions such as Set = , For...Next etc also call the runtime
DLL and ultimately even these fail... (So much for native 'code compilation !)
If an object could be created within the multithreaded procedure, the VB runtime starts behaving properly...
The trouble is,the standard VB instantiator functions fail within the multithreaded procedures...
Therefore, I have used the ThreadAPI.Tlb type library to bypass the Runtime and directly call the OLE/COM
APIs (This can be verified using the Dependency Viewer) and create a dummy object inside the multithreaded
procedure (using the CoCreateInstance API). After this has been done, the runtime DLL starts
'behaving properly and it is possible to
' call all VB functions safely...
Some features and the Do's and Dont's -
1>The multithreader is completely event based, that is the
multithreader notifies the client app of any event such as threads terminating,
or the a priority change...
2>For creating all a programmer has to to is the call the
CreateWin32Thread() Function, and relax ! So no need to fiddle around any
more with ActiveX EXEs !
3>To perform File I/O and to show forms from within threads (which
were earlier not supported) do the following -
Sub MThreadProc(DummyArgument as Variant)
'Your multithreaded procedure
'Some code....
pThread.ObjectInThreadContext.SomeSubroutine
End Sub
'In the above code SomeSubroutine is a Sub or
can be a function defined in the same form or object in which the Sub
MThreadProc is defined (pThread is a reference to the DLL)
Sub SomeSubRoutine
'Your
file I/O code or code for creating and displaying forms (Form1.Show etc) goes
here
End Sub
Special Note: In the above statements, the
ObjectInThreadContext property returns a reference to the object containing the
multithreaded procedure in context to the new thread
4>Always call the END statement when you want to end your app
I must thank Robin Lobel for reporting the form show bug(it was never noticed
by me) also Willian Tarlton who induced be to think until I got a solution, after he reported his
extreme need for file i/o within multithreaded procedures
5>As far as posible do not use the MThreadVB component within the IDE -
Use it only with compiled EXEs
Please mail me at srideepprasad@digitalme.com
if you find bugs or have any suggestions
New ! This article has been updated to include a new
class called ThreadLaunchEX that allows multiple thread creation in real time.
Though it has not been explained, I must say that it can be used just as the
Thread class (used in the Demo) - Only you must identify all threads with a
unique threadId parameter. This is not necessary if you are only using the
simpler Thread class !
Please vote if you find the code useful... Thank You !
A strange "Dissappearance" and a vote of
Thanks !
I must first of all thank all my fellow programmers and developers at
PSC for their tremendous response to this code...
However, recently, this piece
of code (along with almost 500 others) was deleted due to site hacking.
Therefore, I am resubmitting it.. The good news is that Ian, one of the people
behind PSC is sincerely pursuing this matter to bring the hacker to justice...!
(For more information on the hacker attack please visit - (http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=35215&lngWId=1)
| |
Download article
Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzipto decompress it.
Virus note:All files are scanned once-a-day by Planet Source Code for viruses,but new viruses come out every day, so no prevention program can catch 100% of them.
FOR YOUR OWN SAFETY, PLEASE: 1)Re-scan downloaded files using your personal virus checker before using it. 2)NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code. 3)Scan the source code with Minnow's Project Scanner
If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com
|
Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. |
Other 8 submission(s) by this author
|
|
|
Report Bad Submission |
|
|
Your Vote! |
See Voting Log |
|
Other User Comments |
5/30/2002 2:46:40 AM:Srideep Prasad(AUTHOR) IMPORTANT: THIS SUBMISSION IS MANY
MONTHS OLD! IT WAS DELETED DUE TO SITE
HACKING BY A UK BASED HACKER!
FORTUNATELY, IAN, PSC's ADMIN HAS
RESTORED THE SUBMISSION AND ITS VOTE
COUNT! HOWEVER THE VISITOR COUNT WAS
NOT RESTORED UNFORTUNATELY! IN OTHER
WORDS THERE HAS BEEN NO CHEATING - IN
CASE OF DOUBT, PLEASE CONTACT IAN AT
IanIppolito@exhedra.com
|
5/31/2002 4:37:07 AM:Wim Baeyens Thank you for this excellent code. I
don't have a use for it right now but i
will surely use it in the future. It's
also very good to have an article with
it with some background info.
Keep up
the good work !
|
6/26/2002 10:42:09 AM:Mark Davis This is excellent code and a nice
packaging. Very simple solution with a
nice class interface. Thanks for the
submission!
|
6/30/2002 11:25:13 AM:Walter Brebels THANK YOU, i didn't saved my life :), i
didn't knew what all the fuzz wass
about Multi-Threading, since everyone
told me how you did it but not what you
can do with it, thanks a lot, 5 from me
|
7/19/2002 1:46:38 AM:king can't compile
|
7/21/2002 1:53:15 PM:clown king read the readme file in the zip.
it tells you what to do.
|
8/28/2002 4:59:46 PM:Kenneth I'm having problem with the
OnThreadTerminate event in the
ThreadLaunchEX class. Is simpy doesn't
get rasied after a call to
TerminateWin32Thread. The event in the
Thread class works fine. Any ideas
anyone ?
|
9/18/2002 6:39:57 AM: Cool, just what i was looking for. i
need some info on its stabillity and
Garbage collection. on a max how many
threads can i go for without affecting
my parent app. and will the Thread
Object get cleared out of memory the
moment i exit out or my threaded
func.
:) great work
anil oommen
|
9/19/2002 5:05:45 AM: Hi this don´t work in real life stuff
not for me or do i somthing
wrong.
When i start my form i want
to fill 4 lists with data from a
database when i try to fill these in
separate tasks i get vb crasch my
working funktion is in a module and i
put the dummytaskfunction in the form
who calls the real function in the
module.
Any idea of wath im doing
wrong. PLZ Help
|
10/12/2002 12:20:33 PM: Ian i no u !!!
|
10/23/2002 11:05:08 PM: everything works fine with vb
enviroment, but when i make exe of the
program and try to run it, it crashes...
|
10/25/2002 9:29:27 AM: This is very cool code! I only have
one problem. I can't make FILE I/O
work using the ObjectInThreadContext
method. It crashes! Any
thoughts?
Thanks
|
10/29/2002 6:09:57 AM:TrueLyFE I constantly get some variable error
message; "Object variable or With block
variable not set" - I have copied
EVERYTHING I could from the original
source. Right now I am just trying to
get a popupbox running, and once it
works getting in my code... i'll go
back to my labor of getting this to
work :(
|
10/29/2002 6:36:36 AM:TrueLyFE Well, found my problem. Only I have a
new problem now - after 3 launches and
terminations (one started after another
ended) of a thread, the program crashes
and svchost hogs CPU usage. :/
|
10/29/2002 4:02:54 PM: Works great in the IDE, but once
compiled, either P-Code or native, it
crashes on the CreateWin32Thread()
call. I see that others have had this
same issue, I would appreciate it very
much if anyone knows why.
|
10/29/2002 4:17:33 PM: It seems I was referencing a global
object (my homebrew application
object), and you can only reference
properties, methods, objects of the
form that is creating the thread. Also,
a thread must be created from a form
object, a standard class object cannot
be passed as the 'ThreadObject'
argument of CreateWin32Thread() (if
anyone knows the anwser for that let me
know, thanks)
|
11/6/2002 9:03:03 AM:TrueLyFE My problem is a bit different now...
after 3 terminated threads, it crashes,
but svchost isn't hogging anymore. I
stuck in some msgbox's on the
OnThreadFinish - normal VB ones - and
after I click on the third one, my
program exits - no crash, just exits. :/
|
11/11/2002 9:30:29 PM: get a life, get your copies of vs.net
|
11/11/2002 9:35:05 PM: Just joking. This article is super
great...
|
12/2/2002 9:37:54 PM:MR303 now THAT'S a clear 5! (works like a
charm...)
|
12/6/2002 5:37:12 AM: Excellent Code and anaysis. 5 from me
:). Now this code is not useful for me
but i am sure in future i need this.
Keep it up!!
|
12/7/2002 2:15:12 AM: I highly recommend a commercial product
called Thread Factory. Its available
from HalfTime Technologies at
www.halfx.com . This is really a great
tool that does true multithreading and
safely debugs in VB6 IDE.
|
12/12/2002 4:47:30 PM:Reza Alizadeh Man this guy is awesome. Thank you so
much for this great code. I wish we
could give more than 5 globes.
|
12/12/2002 10:37:57 PM: I tried implementing your DLL into my
app, and all it does it creates a
thread which makes a Winsock call, and
awaits data to come back. But it simply
causes it to shut down without any
error.
|
12/16/2002 4:48:59 AM: My problem is very very strange,at
lease i think so.
when it running on
my P4 computer,i always crashes.but if
it run p2 or other cpus have lower
speed,it works very well.anybody knows
the reason?let me know.thanks..
|
12/20/2002 2:06:13 PM:Daniel Pramel Wow, outstanding code. I really like it
:-) 5 * from me.
Daniel
|
1/11/2003 7:40:51 PM:Unimatrix_001 hrm...everytime I try to load up the
project MThread.vbp I get an error
saying:
"Unable to set the version
compatible component"..(my path)..."
MThread.dll
and don't know if
they're connected but then in the demo
project it keeps saying the reference
to the MThreadVB.dll is missing,
although its right there and I've even
pointed to it manually...
Anybody
help?
Thanks...btw I'm sure this is
stunning code, when I get it working! :D
|
1/13/2003 2:09:26 PM:Dennis Fisch hey, this is some great code, indeed,
great for my IRCd ;) to that problem
with the winsock, if you're using the
ocx it makes sense, the new thread does
not know about winsock and therefor
crashes. you may be able to use the
|
3/31/2003 9:33:34 AM: Great code. Although your prime number
routine should be changed!
Change
line For J = 2 To I - 1
to read For J
= 2 To int(sqr(I))
for prime numbers
2 to 50000 I went from >11 secs to <5
secs.
|
4/8/2003 3:57:23 PM: Absolutely great code. Works very well
under most conditions, however, will
always leave a compiled process running
indefinitely if the multithreaded
function does not self terminate. For
example, I have found it virtually
impossible to get the thread to
terminate from within a form_unload
event. Of course, that's just me using
every possible technique I know
(timers, etc.). Crashes under other
particular conditions. Other than
that, good code. Thank you..
|
4/15/2003 7:50:06 PM:Sven T. exactly what i neeeded!
this code is
really great, thanks for sharing it!
|
6/10/2003 2:02:03 AM: I changed the
|
6/10/2003 2:10:58 AM: Great piece of code.
Anyway, i had
changed the "FindPrime" code a bit to
access my database returning a
recordset of 6000 records.
But it
always pops up error saying "Overflow"
at record #4952 and then GPF window
showed up saying "MTHREADDEMO caused an
exception 10H in module MSVBVM60.DLL at
0167:66024d53."
How do i resolve
this ?
Thanks in advance.
|
6/18/2003 6:00:34 PM:Matthew Inns Superb! Thanks for sharing this
|
8/25/2003 9:20:17 PM:Joăo Fernando Kiewel Superior code man! You are the first
one that i "take my hat off" due the
superior code! Keep up the good job!
And of course my 5 globes!
|
|
Add Your Feedback! |
Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.
NOTICE: The author of this article has been kind enough to share it with you. If you have a criticism, please state it politely or it will be deleted.
For feedback not related to this particular article, please click here. |
|