Open a window in a thread

Yes, it simulates the real procedures that will be processing and over which I will show a window showing “wait” until they are finished.

Even with myLoop in place, switching YieldToNextThread in the Thread subclass’s Run event to App.SleepCurrentThread(10) allows the Wait window to show for just a second before the rest of your code in the button’s Action event then executes and closes it.

The better path would be to have the thread perform these long operations and notify its parent using AddInterfaceUpdate both as it progresses and when it’s complete.

The better path would be to have the thread perform these long operations and notify its parent using AddInterfaceUpdate when it’s complete.

Yes, I see the examples are usually making this: putting the loop in a thread. But this is very complicated in that case, many of the procedures in the main loop get access to interface elements, create pictures and save to a SQLite.

I was just trying to show a wait window over a loop that cannot be put in a threat I could not imagine is so complicated this.

You can create pictures in a thread and pass them back to a UI-safe thread by adding them to the Dictionary that you pass to AddUserInterfaceUpdate:

Sub Run()
  dim p as new Picture( 10, 10 )
  p.Graphics.DrawingColor = &cff0000
  p.Graphics.FillRectangle( 0, 0, p.Width, p.Height )
  AddUserInterfaceUpdate( new Dictionary( "p": p ) )

For updating the UI, you would also use AddUserInterfaceUpdate along with the UserInterfaceUpdate event:

Sub UserInterfaceUpdate(data() as Dictionary)
  dim p as Picture = data(0).Value("p")
  self.Backdrop = p
End Sub

Thanks Anthony, but this is more complicated as it may seems, I tried this approach first and it is a very confusing way, and perhaps the need to change many code.

I believed that if I’ve a main method that calls several procedures that take long, the logical idea is:

  • open a window telling “wait”
  • do the procedures
  • close the wait window.
    As this could not be done in the main thread I assumed I could open a new thread for the window wait.

Understood. I can just tell you how I implement threads, and how they’re (arguably) meant to be used. It’s up to you to find what works in your case.

I just tried this - action button on a window to start a thread with this code:

var t as new CounterThread

AddHandler t.UserInterfaceUpdate,  WeakAddressOf app.updateUI      // Wire in the UI updater function for this thread
Addhandler t.run,                  AddressOf     threadCode        // Wire in the main function for this thread
t.Start ()                                                         // Everything ready, can run the thread now

Label1.Text = "Action Done"

and with this in threadCode() :

Var  Count As Integer, d As Dictionary

d = new Dictionary

for i as integer = 0 to 100000
  for ja as integer = 0 to 500
    
  next
next

d.Value("msg") = "Thread done"
t.AddUserInterfaceUpdate (d)

t.sleep (1000)

and the label messages show that the button’s Action event completes without being held up by the loop in the thread.

You need the sleep(1000) since otherwise you lose any pending UI updates.

Yes, I said as much earlier, and speculated that the issues Timers were previously used to address were fixed when Xojo updated the thread object with UserInterfaceUpdate.

Hi Tim, I tried to use your code but… I get several errors:

AddHandler t.UserInterfaceUpdate,  WeakAddressOf app.updateUI

Type “App” has no member named “updateUI”

Addhandler t.run,  AddressOf threadCode

Type mismatch error. Expected delegate Delegate( CounterThread ), but got delegate Delegate( )
Addhandler t.run, AddressOf threadCode

Then the threadCode method uses “t” thas was declared as a local thread, and gets a "This item does not exist

Probably I misunderstand your code, may you help me?

Well you have to write updateUI yourself, to do what you want it to do.

Your threadcode method will need a parameter t as mythreadClass (whatever your thread class is called).

Have a look at the other thread on the forum titled “Understanding threads”.

For what it worths, I’ve often started threads in various places and the next lines in the same method where always executed asynchronously (so both the thread started and the current method finished in parallels); has been true as long as I remember (at least 10 years).

I could be remembering it wrong, or it might be the OS. I know, and checked, and at least three of my Windows-only apps have this sort of code with comments to the effect of what I’ve said. Granted, I may have copied the comments over when reusing code and made a false assumption long ago.

Either way, it doesn’t much matter now. It does work asynchronously in the current version of Xojo.

1 Like