Updating progress bar from other thread and keeping information on "status"

Hello,

I have such problem.

My Multithread application allows user to download special content for them.

I have object which shows list of all avaible data to user.

Then user can select element and see details and if him/she wants can download it.

Download action is created as a task, and send to AsynchronousPythonQue to thread-pool.

Threads take the task and do the task.

To task I pass pointer to function callable, where task can use it to update the status of progress bar. Task have also information if View with progress bar still exists.

If it exists, it updates the value of progress bar.

View have custom event window-update. It handles setting the progress bar value. Tasks send this event to Window event handler from the calling the passed function.

I do this, this way not by wxCallAfter, beacuse I use observer pattern to observe running tasks.

In observer I watch all tasks in background, their ids and progress. If user leaves page with details of avaible data, i destroy the view, send event to tasks that view was destroyed, and switch to not update the progress bar by sending events. Also I clean the EventHandler events que, so wxPython won’t try to update non existing progress bar.

This solution allowed me to achieve on OSX system a functionality, where user can leave page with details, don’t have to wait to end of installation but go to few interesting “items” and start more downloads and nothing crash.

I had to use observer pattern and custom events, beacuse when user leaved page with details, wxCallAfter injected code which was being tryied to get executed, which crashed application beacuse gauge didn’t exist. While now, I clear event handler que, but before that I do that i stop executing events globally for short moment.

The problem is that this solution on Linux system just crashes as hell. Python throws Python Glib critical error : item of id XXX was not found before remove.

(python:17455): GLib-CRITICAL **: Source ID 5096 was not found when attempting to remove it

From time to time, task of downloading object is executed correctly and nothing happens, otherwise it throws this exception.

I have no clue how to handle this problem.

Some tips?

Regards,

Andy

Hello,

its me again.

I have solved this problem.

On OSX I used posting my event to window by calling such code:

self.GetEventHandler().ProcessEvent(event)

Which worked fine and didn’t throw any errors and mistakes.

On Linux system using above code was throwing this critical error mentioned above.

Meanwhile using code like this:

wx.PostEvent(handler, event)
···

If I understand correctly the diffrence is in the way I dispatch my custom event from other thread then GUI-Main thread?

wx.PostEvent is more “legitimate” and error free way?

Best regards

2015-01-08 16:08 GMT+01:00 wxPythonAndy wxpythonitpasoleati@gmail.com:

Hello,

I have such problem.

My Multithread application allows user to download special content for them.

I have object which shows list of all avaible data to user.

Then user can select element and see details and if him/she wants can download it.

Download action is created as a task, and send to AsynchronousPythonQue to thread-pool.

Threads take the task and do the task.

To task I pass pointer to function callable, where task can use it to update the status of progress bar. Task have also information if View with progress bar still exists.

If it exists, it updates the value of progress bar.

View have custom event window-update. It handles setting the progress bar value. Tasks send this event to Window event handler from the calling the passed function.

I do this, this way not by wxCallAfter, beacuse I use observer pattern to observe running tasks.

In observer I watch all tasks in background, their ids and progress. If user leaves page with details of avaible data, i destroy the view, send event to tasks that view was destroyed, and switch to not update the progress bar by sending events. Also I clean the EventHandler events que, so wxPython won’t try to update non existing progress bar.

This solution allowed me to achieve on OSX system a functionality, where user can leave page with details, don’t have to wait to end of installation but go to few interesting “items” and start more downloads and nothing crash.

I had to use observer pattern and custom events, beacuse when user leaved page with details, wxCallAfter injected code which was being tryied to get executed, which crashed application beacuse gauge didn’t exist. While now, I clear event handler que, but before that I do that i stop executing events globally for short moment.

The problem is that this solution on Linux system just crashes as hell. Python throws Python Glib critical error : item of id XXX was not found before remove.

(python:17455): GLib-CRITICAL **: Source ID 5096 was not found when attempting to remove it

From time to time, task of downloading object is executed correctly and nothing happens, otherwise it throws this exception.

I have no clue how to handle this problem.

Some tips?

Regards,

Andy

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 wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

wxPython Infa wrote:

Hello,

its me again.

I have solved this problem.

On OSX I used posting my event to window by calling such code:

>self.GetEventHandler().ProcessEvent(event)|

Which worked fine and didn't throw any errors and mistakes.

On Linux system using above code was throwing this critical error
mentioned above.
Meanwhile using code like this:

>wx.PostEvent(handler, event)|

If I understand correctly the diffrence is in the way I dispatch my
custom event from other thread then GUI-Main thread?
wx.PostEvent is more "legitimate" and error free way?

ProcessEvent will not return until the event has gone through the search for a matching event binding and the handler(s) (if found) has been called and has returned. PostEvent just adds the event to the window's pending event queue and then returns immediately. The events waiting in the queue are processed the next time there is idle time (either almost immediately, or as soon as other system events have been processed and the system event queue becomes empty.)

Since ProcessEvent actually processes the event, it must only be used in the main UI thread. PostEvent can be called from any thread and so is a good way to send events from a non UI thread, which will then be processed in the main UI thread as soon as it's able.

···

--
Robin Dunn
Software Craftsman