Dear all,
Recentlly I met a confusing problem about wx event handling mechanism. I will try my best to describe it.
Assumed there are two event A and B, and OnA() and OnB() are their handlers respective, event A is the first event, and B is the second. So OnA() will be called first, but it will take very long time. What happened next confused me. It seems that before OnA() finished, OnB() will be called. But OnB() depends OnA(), such as some processed result. So there will be a crash or some similiar things.
Maybe there is some mechanism for event handling. But I really want the order of calling OnA() and OnB() is the same as the event-happened order. How to control this mechanism? Or how to handle this kind of problems?
Your help is appreciated.
Thanks very much.
Question about event handling mechanism Topic is solved
You might want to post code for the handlers. If the OnA() takes a long time to process you might want to look at your architecture. Maybe start a thread in OnA() to do the processing and return from OnA() sooner.
Also, look at wxMutex and maybe do some locking so that OnB will wait until OnA is finished.
It is very hard to say for sure what the problem is though with no code.
-Max
Also, look at wxMutex and maybe do some locking so that OnB will wait until OnA is finished.
It is very hard to say for sure what the problem is though with no code.
-Max
-
- I live to help wx-kind
- Posts: 196
- Joined: Tue Dec 07, 2004 8:54 pm
- Location: Essen, Germany
Hello,
Briefly. To avoid the problem you have to add critical section lockers in beginning of both event handlers. Something like that
A little bit more information. As written the above post, it is a good idea to have a separate thread for a long working event handler code. Even in this case the above code will work correctly.
Briefly. To avoid the problem you have to add critical section lockers in beginning of both event handlers. Something like that
Code: Select all
class CClass {
...
wxCriticalSection m_csAccess;
...
void OnA(void);
void OnB(void);
}
...
void CClass::OnA(void) {
wxCriticalSectionLocker lock(m_csAccess);
...
}
void CClass::OnB(void) {
wxCriticalSectionLocker lock(m_csAccess);
...
}
It probably won't be.It seems that before OnA() finished, OnB() will be called.
The wx event system processes events in idle time, sequentially. So if the OnA() event is queued first, and is well-behaved, it will run to completion and return before any other event is called, including internal wx events. In fact this is often a problem: the gui won't be updated during this time, the app will appear to freeze... So very time-consuming functions need to be written to avoid the problem e.g. by spawning a thread for the time-consuming stuff, or by calling wxYield().
Which is why I said "well-behaved". If OnA() calls wxYield(), it's likely that the OnB() event will be processed, which is not what you want. There's also the gotcha that some wx functions themselves call wxYield() e.g. wxBusyCursor().
So, depending on your code, it'll probably work OK. Try it and see.
Regards,
David