Recent

Author Topic: ShowMessage() runs in a different thread?  (Read 1041 times)

JimKueneman

  • Full Member
  • ***
  • Posts: 189
ShowMessage() runs in a different thread?
« on: December 28, 2020, 09:02:47 pm »
I am struggling with a bug in my code that I believe occurs because it looks like the ShowMessage dialog is not running in the main thread.  When the dialog is showing (executed from the main thread) I also have a timer running in the main thread that actually continues to tick when the ShowMessage dialog is shown causing me issues.  The expectation was ShowMessage would block the main thread including the timer...  am I missing something here?

Jim

Thaddy

  • Hero Member
  • *****
  • Posts: 10786
Re: ShowMessage() runs in a different thread?
« Reply #1 on: December 28, 2020, 09:04:28 pm »
It is actually the timer that runs in a thread, not the showmessage.
But as long as the showmessage is active, there should not be any screen updates from the timer. That is supposed to be blocked since showmessage is modal.
« Last Edit: December 28, 2020, 09:06:17 pm by Thaddy »

JimKueneman

  • Full Member
  • ***
  • Posts: 189
Re: ShowMessage() runs in a different thread?
« Reply #2 on: December 28, 2020, 09:06:07 pm »
Thanks, that just occurred to me... is this just OS X that does this or does Linux do it as well?  I know Windows has two ways of doing it... on the same thread (message pump) or on a separate thread.

Jim

JimKueneman

  • Full Member
  • ***
  • Posts: 189
Re: ShowMessage() runs in a different thread?
« Reply #3 on: December 28, 2020, 09:07:55 pm »
Is there a way to call it in the context of the main thread built in?  If not how would that be done?  PostMessage?

JimKueneman

  • Full Member
  • ***
  • Posts: 189
Re: ShowMessage() runs in a different thread?
« Reply #4 on: December 28, 2020, 09:09:52 pm »
It is actually the timer that runs in a thread, not the showmessage.
But as long as the showmessage is active, there should not be any screen updates from the timer. That is supposed to be blocked since showmessage is modal.

I am setting flags in the timer tick that I am not expecting to be set during the showing of the dialog.

JimKueneman

  • Full Member
  • ***
  • Posts: 189
Re: ShowMessage() runs in a different thread?
« Reply #5 on: December 28, 2020, 09:13:13 pm »
Since it is in a thread I guess the most portable way is to create my own thread and send the tick through Synchronize. 

MarkMLl

  • Hero Member
  • *****
  • Posts: 2521
Re: ShowMessage() runs in a different thread?
« Reply #6 on: December 28, 2020, 09:13:56 pm »
Stop. All GUI-related activities run from a single thread, but various things generate events which are dequeued by what used to be called the message loop but which in Delphi and Lazarus is generally hidden.

So a keyboard action will generate an event, a mouse action on the application area of a window will generate an event, a window resize request will generate an event, and so on.

In addition, a timer firing will generate an event, and broadly speaking dialogues being opened or manipulated will rely on or result in events... please excuse a bit of handwaving here.

When you display a dialog(ue), including calling ShowMessage(), the created window might be modal or modeless. A modal dialogue generally has to be closed before other activities can continue, but this doesn't necessarily imply that other windows won't respond to events. A modeless window will continue to run in parallel.

If you start a background thread then you CANNOT use any part of the API which manipulates the GUI directly. Broadly speaking, I believe that this limitation is shared by all comparable software.

Delphi and Lazarus (encompassing their class libraries) provide the Synchronise() method that allows a background thread to interact with the GUI, this is synchronous but if you look at the wiki you'll see that tehre are also asynchronous equivalents i.e. which do not block the background thread.

I suggest reviewing what you're doing and your overall understanding in view of that little lot, I've skimped on URLs etc. because of the importance of preventing you from going on a wild goose chase.

MarkMLl






« Last Edit: December 28, 2020, 09:26:17 pm by MarkMLl »
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

JimKueneman

  • Full Member
  • ***
  • Posts: 189
Re: ShowMessage() runs in a different thread?
« Reply #7 on: December 28, 2020, 09:19:59 pm »
Stop.

This is a cross complier library and needing to remember to call Stop would be painful.  Also now that I know that is run in a different thread I can see other places for disaster.  I think it warrants making my own timer with a thread and Synchronize... I don't think the TTimer is the right tool for this job.

Thanks,
Jim

MarkMLl

  • Hero Member
  • *****
  • Posts: 2521
Re: ShowMessage() runs in a different thread?
« Reply #8 on: December 28, 2020, 09:26:50 pm »
My "stop" referred to the fact that you were flailing around while I was trying to type up an outline of how things worked, and I appreciated your pausing until I had a chance to finish. I grant that I am not an expert in Macs but what I've given you is a broad cross-platform outline that I believe applies. The important thing is that you don't launch into threads half-cocked when you don't need to.

Noting one of your other questions, the description I gave you was, broadly speaking, based on Linux. I suspect that when Thaddy said that a timer ran in a thread he was referring to what happened in the background, and unless he specifically clarifies things it's probably best to assume that the timer event executes in the context of the main (GUI) thread.

MarkML
« Last Edit: December 28, 2020, 09:35:20 pm by MarkMLl »
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

JimKueneman

  • Full Member
  • ***
  • Posts: 189
Re: ShowMessage() runs in a different thread?
« Reply #9 on: December 28, 2020, 10:21:00 pm »
My "stop" referred to the fact that you were flailing around while I was trying to type up an outline of how things worked, and I appreciated your pausing until I had a chance to finish. I grant that I am not an expert in Macs but what I've given you is a broad cross-platform outline that I believe applies. The important thing is that you don't launch into threads half-cocked when you don't need to.

Noting one of your other questions, the description I gave you was, broadly speaking, based on Linux. I suspect that when Thaddy said that a timer ran in a thread he was referring to what happened in the background, and unless he specifically clarifies things it's probably best to assume that the timer event executes in the context of the main (GUI) thread.

MarkML

Thanks I have a lot of code that runs in threads so I do understand how tricky they can be... so let me be more specific in what I am doing and what I am seeing in OS X.  I am effectively creating a statemachine engine where I create a statemachine object that does tasks in each state (a method in the class for each state) and it waiting for callbacks or other events to move through the statemachine.  On the side I have a TTimer running that is looking for a hung statemachine or is used to move to the next state if the event does not occur within a specific time.  What threw me for a loop was in one of the states that I had it ShowMessage to notify the user.  I was having this weird bug and put a breakpoint in the state (method) at the end where it was looking for timer tick timeout.  What happened was the code was in the method and paused on ShowMessage when if I waited long enough to respond to the message the _same_ method was called through the timer tick code and triggered the breakpoint in the timeout.   After resuming the program I answered the ShowMessage to close it and the main thread code continued in that method right after the call to ShowMessage.

The timer tick was processed and its OnTimer event fired while the main thread code was paused in the ShowMessage call.  I was not expecting that.

Jim

MarkMLl

  • Hero Member
  • *****
  • Posts: 2521
Re: ShowMessage() runs in a different thread?
« Reply #10 on: December 28, 2020, 10:31:19 pm »
Sorry about yelling at you earlier... or maybe you didn't see that bit :-)

I tend to be pretty paranoid with assertions checking that methods are- or aren't- running in the GUI thread. In a number of cases I also try to write such that a method/function/etc. can be called in either the GUI or a background thread... I can thoroughly recommend those precautions.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 10786
Re: ShowMessage() runs in a different thread?
« Reply #11 on: December 28, 2020, 10:36:04 pm »
Mark, PostMessage is async, sendmessage is synced.
The former is suitable for thread communication, the latter less so, since it causes blocking.
« Last Edit: December 28, 2020, 10:37:43 pm by Thaddy »

MarkMLl

  • Hero Member
  • *****
  • Posts: 2521
Re: ShowMessage() runs in a different thread?
« Reply #12 on: December 29, 2020, 10:54:08 am »
Mark, PostMessage is async, sendmessage is synced.
The former is suitable for thread communication, the latter less so, since it causes blocking.

Yes, I worked through them in detail a few months ago and tightened up the wiki page a little bit (I'd had some "interesting" experiences due to spurious APMs). But I was trying to get stuff typed rapidly in the messages above to stop OP flailing so was sticking to what I was confident I could recall correctly.

Mark
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018