Threads in Visual Basic (Article, With Example)
Author: David Nishimoto
Version Compatibility: Visual Basic 6
Introduction to using multiple threads in VB6. For more detailed information, see Daniel Appleman's article A Thread to Visual Basic.
Instructions: Copy the declarations and code below and paste directly into your VB project.
Scope Threads provide an concurrent environment to accomplish multiple tasks. The cpu time-shares between each thread based on a priority number. The higher the priority number the more frequent the process is time-shared into the kernel address space. Each three has its own stack. Once a thread begins to execute it can run indefinitely or until the thread has been terminated. Internal to a thread function is a looping structure. The looping structure continues to loop until a signal is set. The ellasped time to wait for an incoming signal can be adjusted slowing down the frequency of the looping cycle. Since threads can process critical paths of instruction and more then one thread can be started concurrent tasking can occur. Background Two threads are created to run into the address space. AddressOf provides the address for the function to assign to the thread lThreadHandle1 and lThreadHandle2 are the thread handles to terminate the thread. lThreadHandle1 = CreateThread(ByVal 0&, ByVal 0&, AddressOf test_function, ByVal 0&, 0, lpThreadID) lThreadHandle2 = CreateThread(ByVal 0&, ByVal 0&, AddressOf test_function2, ByVal 0&, 0, lpThreadID) A event single is created lEventHandle = CreateEvent(ByVal 0&, False, False, ByVal 0&) A signal is generated for an event. lRC = SetEvent(lEventHandle) The WaitForSingleObject receives the signal handle and waits for an incoming signal. If the signal is received ret is assigned a value not equal to 0. ret = WaitForSingleObject(lEventHandle, 10) Assumptions: 1) Do not run the vb thread application from debug. Run the application as a compiled executable. Instead compile and run the executable. Call TerminateProcess(GetCurrentProcess, ByVal 0&) will terminate the current vb process 2) Test each function first before embedding into the thread frame work application. 3) Make sure the project is compiled as P-Code (executable will fault if the binary is not P-Code) Visual Basic Sample: Module: The module code has two functions define: test_function and test_function2 which are associated to a thread. The thread remains in the critical path until a signal is received. Once the signal is received the thread finish executing the critical path and terminates. Option Explicit Public Declare Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Public Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long Public Declare Function GetCurrentProcess Lib "kernel32" () As Long Public Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Public Declare Function CreateEvent& Lib "kernel32" Alias "CreateEventA" (ByVal lpEventAttributes As Long, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpname As String) Public lThreadHandle1 As Long Public lThreadHandle2 As Long Public lEventHandle As Long Public Sub Main() frmOutput.Show End Sub Public Sub test_function() Dim i As Long Dim ret As Long i = 0 Do i = i + 1 'Sleep 10 frmOutput.txtStream1 = i DoEvents ret = WaitForSingleObject(lEventHandle, 10) Loop Until ret = 0 End Sub Public Sub test_function2() Dim i As Long Dim ret As Long i = 0 Do i = i + 1 'Sleep 500 frmOutput.txtStream2 = i ret = WaitForSingleObject(lEventHandle, 500) Loop Until ret = 0 End Sub Form: The form contains two command buttons to start and stop the thread. When the command button is pressed the thread for test_function is created, a second thread for test_function2 is created, and a event object used to signal termination of all looping is created. When the stop button is pressed, a signal is broadcast for the event object handle and the thread handles are terminated. Private Sub cmdStart_Click() Dim lpThreadID As Long lThreadHandle1 = CreateThread(ByVal 0&, ByVal 0&, AddressOf test_function, ByVal 0&, 0, lpThreadID) lThreadHandle2 = CreateThread(ByVal 0&, ByVal 0&, AddressOf test_function2, ByVal 0&, 0, lpThreadID) lEventHandle = CreateEvent(ByVal 0&, False, False, ByVal 0&) End Sub Private Sub cmdStop_Click() Dim lRC As Long lRC = SetEvent(lEventHandle) If lThreadHandle1 > 0 Then Call TerminateThread(lThreadHandle1, ByVal 0&) End If If lThreadHandle2 > 0 Then Call TerminateThread(lThreadHandle2, ByVal 0&) End If lThreadHandle1 = 0 lThreadHandle2 = 0 End Sub Private Sub Form_Unload(Cancel As Integer) If lThreadHandle1 > 0 Then Call TerminateThread(lThreadHandle1, ByVal 0&) End If If lThreadHandle2 > 0 Then Call TerminateThread(lThreadHandle2, ByVal 0&) End If Call TerminateProcess(GetCurrentProcess, ByVal 0&) End Sub