Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating threads in VB

Status
Not open for further replies.

phzero

Programmer
Feb 14, 2002
86
ZA
Hi All,
I am a seasoned C++ developer and have been programming in VB for 11 months now. For the first time I am faced with having to create a thread in VB and I do not know how. Is there an equal to CreateThread() or _beginthread() in VB. I have tried to create a VB wrapper but it failed on creation, and very abruptly just so by the way. I know a little about classes in VB but am unsure about how to use it and whether it can be used to create multiple thread. Any help will be appreciated. Thanks you guys.
 
There is no "official" multi-threading in VB 6 but there is in VB.NET. Do you need "multi-threading" or the capability of interrupting long running piece of code? If it is the latter, you can occasionally execute a DoEvents in your long-running code to allow other events to be handled. The interrupt will be processed on the same stack and thread as the interrupted code and the interrupted code will not resume executing until the interrupting code is finshed. I've used it to allow user interaction after having started a WebBrowser request involving navigation of 5 screens, utilizing asynchronus DocumentComplete events. Forms/Controls Resizing/Tabbing Control
Compare Code (Text)
Generate Sort Class in VB or VBScript
 
As JohnYingling says, there is no real native support for threads in VB6. Interestingly, VB5 was thread safe, meaning you could get away with using the API to spawn new threads (via CreateThread) and the code remained stable. For some reason this facility was removed in VB6.

However the trick still seems to work (in the sense that you don't get odd crashes) if you compile your program to P-Code rather than to native code.
 
You can get some real strange results trying to use CreateTrhead() in VB. And never, ever under any circumstances try to debug an applications in VB if you do use CreateThread(), that will have terrible results.

With the way VB handles variables, etc. to make itself thread-safe, you don't get what you would expect if you come from the C++ realm. The only way in VB6 to get get similar results is to create an ActiveX EXE for your threads. Then, in that object, you have to post a timer or some event in order to get the processes to run concurrentlys. Otherwise, you may have another thread, but the VB thread will still wait for your method call to finish before returning. So, you need that method to be quick, and just just post a message that it can pick up later and finsh doing the work.
 
Thanks again all. I appreciate your responses. I do realise that nothing can measure up to the great power and flexibiblity C++ has to offer, but I am a bit disappointed in the fact that VB does not have an equavilent (apart from Timers, which are not really threads if you know what I mean) and even more so that it does not flawlessly handle wrapper functions of the such. This leaves me with having to write DLL's in C++ and using them as CALLBACKS from VB. Thanks again guys for your input.
 
Well, as I said in my first post, and contrary to FRoeCassNet's assertions, you can get multiple threads running concurrently in VB6 (although they are quite correct about the debugging issue). And you don't have to resort to ActiveX EXEs. I'm in a different office today from my development machine, so I don't have any of my code available at the moment to illustrate this.
 
Hi strongm, could you please forward the sample code when you have a mo. Thanks for all your help.
 
No stress. I'll wait. Have a good day.
 
Realize that VB6 does not have "official" multi-threading but that VB.NET does so it is no longer a characteristic of VB itself, but rather the version. Forms/Controls Resizing/Tabbing Control
Compare Code (Text)
Generate Sort Class in VB or VBScript
 
As promised. Here's code that needs to go in a module that has two different Subs that we can invoke in threads, although we're just using AsyncThread2 in this example (on the other hand the majority of the API declarations which bulk out the code are actually for AsyncThread).
[tt]
Option Explicit

'In a module
Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function GetCurrentProcess Lib "kernel32" () As Long
Public Declare Function GetTickCount Lib "kernel32" () As Long

Public Const PM_NOREMOVE = &H0

Public Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Public Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As SECURITY_ATTRIBUTES, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long
Public Declare Function ResetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Public Declare Function MsgWaitForMultipleObjects Lib "user32" (ByVal nCount As Long, pHandles As Long, ByVal fWaitAll As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As Long) As Long

Public Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
'
Public Type POINTAPI
x As Long
y As Long
End Type
'
Public Type MSG
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
'
Private Const WAIT_ABANDONED = &H80&
Private Const WAIT_ABANDONED_0 = &H80&
Private Const WAIT_FAILED = -1&
Private Const WAIT_IO_COMPLETION = &HC0&
Private Const WAIT_OBJECT_0 = 0
Private Const WAIT_OBJECT_1 = 1
Private Const WAIT_TIMEOUT = &H102&
'
'
'
Public Const QS_MOUSEBUTTON = &H4
Public Const QS_MOUSEMOVE = &H2
Public Const QS_PAINT = &H20
Public Const QS_POSTMESSAGE = &H8
Public Const QS_SENDMESSAGE = &H40
Public Const QS_TIMER = &H10
Public Const QS_KEY = &H1
Public Const QS_HOTKEY = &H80
Public Const QS_MOUSE = (QS_MOUSEMOVE Or QS_MOUSEBUTTON)
Public Const QS_INPUT = (QS_MOUSE Or QS_KEY)
Public Const QS_ALLINPUT = (QS_SENDMESSAGE Or QS_PAINT Or QS_TIMER Or QS_POSTMESSAGE Or QS_MOUSEBUTTON Or QS_MOUSEMOVE Or QS_HOTKEY Or QS_KEY)
Public Const QS_ALLEVENTS = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY)
'
'Public Const QS_ALLINPUTNOTTIMER = (QS_SENDMESSAGE Or QS_PAINT Or QS_POSTMESSAGE Or QS_MOUSEBUTTON Or QS_MOUSEMOVE Or QS_HOTKEY Or QS_KEY)
'
'

Public hThread As Long
Public hThreadID As Long
Public EndThread As Boolean ' Flag used to allow us to end the AsyncThread2 function when we close down

' This is a more complex example than AsyncThread2
Public Sub AsyncThread()
Dim hEvent As Long
Dim SA As SECURITY_ATTRIBUTES
Dim result As Long
Dim Starttime As Long
Dim mymsg As MSG



SA.nLength = Len(SA)


hEvent = CreateEvent(SA, False, False, "")

'Debug.Print hEvent
Starttime = GetTickCount

' Only do for 30 seconds
Do Until GetTickCount - Starttime > 30000
result = MsgWaitForMultipleObjects(1, hEvent, False, 5000, QS_ALLEVENTS)
Debug.Print result
If result = WAIT_TIMEOUT Then MsgBox ("Idle!")
If result = WAIT_OBJECT_1 Then
Debug.Print "In use"
PeekMessage mymsg, 0, 0, 0, PM_NOREMOVE
End If

ResetEvent hEvent

Loop

CloseHandle hEvent

End Sub

Public Sub AsyncThread2()
' The use of the EndThread flag here is simply for the sake of this example
' It tries to ensure that this sub is exited when the thread it is running in is
' terminated. This stops the VB IDE crashing.
Static AsyncCounter As Long
EndThread = False
Do Until AsyncCounter = 32000 Or EndThread = True
AsyncCounter = AsyncCounter + 1
Form1.Text1.Text = AsyncCounter
Loop

End Sub
[/tt]
Ok, now you want a form with two text boxes and a command button. If you compile the program, compile it to p-code rather than native code.
[tt]
Option Explicit

Private Sub Command1_Click()
Dim AsyncCounter As Long

' Use the simpler example
hThread = CreateThread(ByVal 0&, ByVal 0&, AddressOf AsyncThread2, ByVal 0&, ByVal 0&, hThreadID)
CloseHandle hThread ' We don't need the open handle


' OK, here's a tight loop that defers to the OS
Do Until AsyncCounter = 32000 Or EndThread = True
AsyncCounter = AsyncCounter + 1
Form1.Text2.Text = AsyncCounter
' Defer to OS
DoEvents
Loop

End Sub

Private Sub Form_Unload(Cancel As Integer)
'If the thread is still running, close it
If hThread <> 0 Then
EndThread = True
TerminateThread hThread, 0
End If

End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top