Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application hangs after posting message to previously not shown frame

I have PageControl with two TabSheets. On each of them there is a Frame, lets call it Frame2. I have a background thread which is posting message to Frame2 when it has finished its task. The Frame2 is on the second TabSheet so it is not visible when user starts application.

The problem is that my application stops refreshing its content when the thread posted message to Frame2, but only in case when Frame2 has not been previously shown. This leads me to think that message queue for the Frame2 has not yet been initialized and it gets initialized when the Frame2 is shown on the screen for the first time. Am I guessing correct?

Could someone give me tips how to initialize message queue right after constructing the Frame2 so it could listen messages immediately?

like image 346
Wodzu Avatar asked Jul 31 '15 13:07

Wodzu


People also ask

Can I restart a hung application?

However, this prevents the average user from closing and restarting a hung application and often ends in a reboot. The operating system defines an application hang as a UI thread that has not processed messages for at least 5 seconds.

How long does it take for a hung application to stop?

After 5 seconds, they will try to terminate a hung application. Next to crashes, application hangs are the most common source of user disruption when working with Win32 applications. There are many different root causes for application hangs, and not all of them manifest themselves in an unresponsive UI.

What causes application hangs?

There are many different root causes for application hangs, and not all of them manifest themselves in an unresponsive UI. However, an unresponsive UI is one of the most common hang experiences, and this scenario currently receives the most operating system support for both detection as well as recovery.

What is application hang in Linux?

The operating system defines an application hang as a UI thread that has not processed messages for at least 5 seconds. Obvious bugs cause some hangs, for example, a thread waiting for an event that is never signaled, and two threads each holding a lock and trying to acquire the others.


1 Answers

It's not that the frame doesn't have a message queue — it's threads that have message queues, not windows — but that the frame doesn't yet have a window handle. The window handle is most likely only created when the frame is first shown, unless you post it a message, in which case the window is created on demand.

If you attempt to post a message to it, you probably have a statement like this: PostMessage(Frame2.Handle, ...).

Reading the Handle property of a component will cause that component to create its window, if it doesn't already have a handle. When that happens in your secondary thread, then the frame's window is created belonging to that secondary thread. That can lead to any number of problems down the line. Like all VCL windows, the frame's window needs to belong to the main, VCL thread.

Even if you ensure that the frame's handle is created in the main thread before you direct messages to it (such as by calling HandleNeeded in the main thread), there's still a chance that reading the frame's Handle property will cause problems. This is because a VCL control might re-create its window. Then, once again, reading the Handle property may trigger creation of the frame's window in the wrong thread.

The safe technique is for the frame to to call AllocateHWnd to create a dedicated message-only window. Do that in the frame's constructor so it's guaranteed to happen in the main thread, and then post messages there. When you create the window, you'll provide a callback method that will be called any time that window receives a message. That callback method should belong to the frame control so that it has access to all the fields and methods of the frame it's associated with.

like image 153
Rob Kennedy Avatar answered Nov 11 '22 15:11

Rob Kennedy