I know there have been some similar posts to this, but I haven’t yet found one that gives a solution to my problem.
I have a wxPython program that has multiple long running tasks that may run simultaneously. When one of them is running, it updates the part of the GUI by using pubsub along with wx.CallAfter (similar to what is shown here, http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/). Since the thread continues to run but I want the GUI to update quickly, right after wx.CallAfter I call wx.SafeYield so that the GUI is updated very quickly. If I don’t use this Yield, then the GUI is updated extremely slowly/late because there is no IDLE time for it to be processed (all time is spent processing the long running task). This works fine for me, as long as only one thread is running. If multiple threads are running, then I occasionally get an error for recursive calls to Yield (one thread calls a yield and then the other thread calls yield before the previous one finishes).
What is the best way around this issue? Both threads could potentially be trying to update the GUI 10+ times per second. I’ve made the function called by wx.CallAfter as quick as possible (all it does is update a few GUI widgets and returns). Usually I don’t have an issue, but sometimes I get the recursive calls error. If I add more threads or update the GUI quicker, then the occurrences of the recursive calls would also increase.
You could try having a Do_Safe_Yield function and a
Lock_Unlock_Yield function where the first one checks a thread flag
for is it safe to do the yield then calls the second before doing
the actual Yield and then calling the Lock_Unlock_Yield in unlock
mode, Lock_Unlock_Yield would set/clear a flag in each existing
function. BUT unless you set the check up to do a small sleep and
retry, blocking your thread, then you will still get cases when your
GUI is slow to update and if you do you will be slowing your
processing.
···
On 01/03/13 00:54, Scott wrote:
Hello all,
I know there have been some similar posts to this, but I haven't
yet found one that gives a solution to my problem.
I have a wxPython program that has multiple long running tasks
that may run simultaneously. When one of them is running, it
updates the part of the GUI by using pubsub along with
wx.CallAfter (similar to what is shown here,
).
Since the thread continues to run but I want the GUI to update
quickly, right after wx.CallAfter I call wx.SafeYield so that the
GUI is updated very quickly. If I don’t use this Yield, then the
GUI is updated extremely slowly/late because there is no IDLE time
for it to be processed (all time is spent processing the long
running task). This works fine for me, as long as only one thread
is running. If multiple threads are running, then I occasionally
get an error for recursive calls to Yield (one thread calls a
yield and then the other thread calls yield before the previous
one finishes).
What is the best way around this issue? Both threads could
potentially be trying to update the GUI 10+ times per second.
I’ve made the function called by wx.CallAfter as quick as possible
(all it does is update a few GUI widgets and returns). Usually I
don’t have an issue, but sometimes I get the recursive calls
error. If I add more threads or update the GUI quicker, then the
occurrences of the recursive calls would also increase.
Thanks,
-Scott
– You received this message because you are subscribed to the Google
Groups “wxPython-users” group.
To unsubscribe from this group and stop receiving emails from it,
send an email to .
For more options, visit .
I know there have been some similar posts to this, but I haven't yet
found one that gives a solution to my problem.
I have a wxPython program that has multiple long running tasks that may
run simultaneously. When one of them is running, it updates the part of
the GUI by using pubsub along with wx.CallAfter (similar to what is
shown here, wxPython and Threads - Mouse Vs Python).
Since the thread continues to run but I want the GUI to update quickly,
right after wx.CallAfter I call wx.SafeYield so that the GUI is updated
very quickly. If I don't use this Yield, then the GUI is updated
extremely slowly/late because there is no IDLE time for it to be
processed (all time is spent processing the long running task). This
works fine for me, as long as only one thread is running. If multiple
threads are running, then I occasionally get an error for recursive
calls to Yield (one thread calls a yield and then the other thread calls
yield before the previous one finishes).
You really should not be calling any of the yield functions from other threads. It implements a temporary nested event loop which fetches and dispatches native messages as events. That is pretty unsafe for non-UI threads. wx.CallAfter calls wx.WakeUpIdle, (via wx.PostEvent) which will trigger a null message on the UI thread so the event that will handle the CallAfter will happen as soon as possible. If your worker threads are so CPU intensive that they don't allow the UI thread to run in a timely enough manner then you should probably arrange a way for them to pause until the UI thread has had a chance to run long enough to handle the CallAfter. For example, using a threading.Event to wait for the called function to be finished. The wx.lib.delayedresult module provides a framework to help you not only do that but to get the results back from the called functions if you need it. You may also want to google for wxAnyThread for another implementation.