susan wrote: Wed Nov 12, 2025 3:25 am...I am a little surprised that threads are the recommended way (which feels like diving in the deep end) in a
BASIC language to update the UI while doing something else in what is essentially a beginners program in the language.
Hi @susan. What you should be
(pleasantly) surprised about is to find a BASIC language that supports threading so easily.
Here's a simple example which uses a timer to demonstrate the unblocked functionality of the main event loop and UI when a thread is running.
Code: Select all
; create your own custom event
#PB_MyProcedureIsDone = #PB_Event_FirstCustomValue
Procedure slowProcedure(dummy)
For i = 0 To 300000000
Pow(27.0, 1/3.0)
Next
PostEvent(#PB_MyProcedureIsDone)
EndProcedure
OpenWindow(0, 0, 0, 300, 200, "Simple Thread Example",
#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(0, 10, 10, 280, 30, "", #PB_Text_Center)
ButtonGadget(1, 10, 160, 280, 30, "Start Procedure")
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
appQuit = #True
Case #PB_Event_Timer
If EventTimer() = 0
SetGadgetText(0, "Procedure running for " + timer + " seconds...")
timer + 1
EndIf
Case #PB_Event_Gadget
If EventGadget() = 1
timer = 1
DisableGadget(1, #True)
AddWindowTimer(0, 0, 1000)
CreateThread(@slowProcedure(), 0)
EndIf
Case #PB_MyProcedureIsDone
DisableGadget(1, #False)
RemoveWindowTimer(0, 0)
SetGadgetText(0, "Procedure completed in " + timer + " seconds!")
EndSelect
Until appQuit
And here's an expanded example to further demonstrate how to stop a thread safely and elegantly. Please note that although there is a function to kill threads, aptly named
KillThread(), it's not recommended.
Code: Select all
; create your own custom event
#PB_MyProcedureIsDone = #PB_Event_FirstCustomValue
Global killThreadSwitch = #False
Procedure slowProcedure(dummy)
For i = 0 To 300000000
Pow(27.0, 1/3.0)
If killThreadSwitch
Break
EndIf
Next
If Not killThreadSwitch
PostEvent(#PB_MyProcedureIsDone)
EndIf
EndProcedure
OpenWindow(0, 0, 0, 300, 200, "Simple Thread Example",
#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(0, 10, 10, 280, 30, "", #PB_Text_Center)
ButtonGadget(1, 10, 120, 280, 30, "Start Procedure")
ButtonGadget(2, 10, 160, 280, 30, "Force Stop Procedure")
DisableGadget(2, #True)
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
appQuit = #True
Case #PB_Event_Timer
If EventTimer() = 0
SetGadgetText(0, "Procedure running for " + timer + " seconds.")
timer + 1
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case 1
timer = 1
killThreadSwitch = #False
DisableGadget(1, #True)
DisableGadget(2, #False)
AddWindowTimer(0, 0, 1000)
CreateThread(@slowProcedure(), 0)
Case 2
killThreadSwitch = #True
DisableGadget(1, #False)
DisableGadget(2, #True)
RemoveWindowTimer(0, 0)
SetGadgetText(0, "Procedure killed after " + timer + " seconds.")
EndSelect
Case #PB_MyProcedureIsDone
DisableGadget(1, #False)
DisableGadget(2, #True)
RemoveWindowTimer(0, 0)
SetGadgetText(0, "Procedure completed in " + timer + " seconds.")
EndSelect
Until appQuit
Hope it helps.
