Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
I have a CButton derived class that's being written to at a very high rate from an independent thread (does it through a PostMessage, the handler does SetWindowText). Under some circumstances, the independent thread works faster than the UI updates, so its PostMessage calls result in freezing the UI.

This isn't a huge problem in Windows, it only happens under certain circumstances and I already figured out a patch that makes it work all the time, but it causes major headaches in Linux (being run through WINE).

I was wondering if there's a way to essentially do what SetWindowText() does without actually calling that call (member variable I can load)? Problem is the call works synchronously and is very ineffective when being called on a window that isn't even visible (slow even though there's no drawing occurring, and yes, I know it's a SendMssage with WM_SETTEXT). It's faster to check the window status yourself but if you do that you may miss updating the window when it's closed.

I guess I can replace the handler with just loading variables that are interpreted on a custom paint/draw routine. Just want to know if anyone else has suggestions for high-speed text updates to a CButton object (in a multithreaded environment).
Posted
Comments
pasztorpisti 17-Jul-13 18:11pm    
If every message has its own copy of the text parameter your solution shouldn't crash/freeze/deadlock even if it isn't effective. If the next message can possibly destroy/overwrite the string of a previous message that is still in the message queue of the gui then that can be a problem. The freeze can also be something wine specific (maybe it has a max size...). Still the suggestions given in the answers make sense. You shouldn't update the gui too often and this is true for basically every kind of background task that gives feedback on the gui.
Albert Holguin 17-Jul-13 19:04pm    
It freezes the UI because it fills up the queue with messages that the UI can't process... problem is a lot worse in Wine so it might partially be their implementation of the window messaging but I'm still trying to find a happy medium so the software works well regardless of OS

Instead of sending messages and/or calling the button write code a lot, why don't you just write to a value at whatever rate you want and have the button update itself every 500 milliseconds or so? You could either use a timer with a fixed interval, or have the button update code send itself a "one-off" timer when it completes the current update task. That way the message loop doesn't get bogged down, and the button updates will back off a little if the system otherwise gets busy.

What I said here applies to updating a number. If the data instead is complex or is text, create a new data item and update (atomically) the pointer to the "current" data. Be sure to properly handle memory management for the stale data (don't leak). If there is only one logic path for the data updates, you could use double buffering and a "current value" pointer (which fixes the leak problem). If there is more than one update path, you will need a more complicated buffering scheme.
 
Share this answer
 
Comments
Albert Holguin 17-Jul-13 13:05pm    
I actually thought of this this morning (have the button update himself periodically), it's actually a pretty good idea... I might just try it out and see how it works in practice... thanks!
Albert Holguin 18-Jul-13 14:31pm    
Quick update... this is working out like a charm... the UI updating slower is smooth as butter, plus the CPU usage is a lot lower than it was before. Most importantly, this wasn't a major software architecture change.
H.Brydon 18-Jul-13 18:21pm    
Good to hear. Thanks for the feedback. Good luck with your app.
You have to have control how often an update is useful. I guess at more than 50 update per second makes really no sense. Use PostMessage (only fills the message queue) and WM_SETTEXT.

Run a own thread which updates the text by reading a prepared variable. Only update if changed.

Mantra: Avoid doing unneeded stuff to speed up.
 
Share this answer
 
Comments
Albert Holguin 17-Jul-13 11:08am    
I agree with the throttling, only that this is existing software using an existing architecture. The updates are occurring within a DLL that doesn't know the state of the entire software, this causes conflicts as to knowing what is and isn't important. I guess some changes to the architecture would fix this more permanently but that's not an easy decision since it's software that other people have written DLLs to (that would break the interface). Thanks for the suggestions... :)
KarstenK 18-Jul-13 2:12am    
the software is bad designed. A GUI should only update the owner. The danger of crashes and bugs are too big.

An example "Which mistake can get avoided to create great software"
Albert Holguin 18-Jul-13 10:07am    
Well it's very complex software with a very subtle problem. The GUI is being updated by the owner, but based on messages from an independent thread. The complexity of the architecture is compounded by having multithreading and dll's.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900