-
-
Notifications
You must be signed in to change notification settings - Fork 24
No obvious way to await till idle #44
Comments
How much experience do you have with vanilla asyncio? Also, if you could tell me how the examples are out of date or not useful, that would be good. |
Not a huge amount, enough to get my head around the basic concepts, but struggling to understand how this works when a GtkApplication is already taking the main coroutine. I'm also seeing some potential unresponsiveness, for example if the |
You need to use asyncio.sleep instead of time.sleep, so that the loop can run. |
@stuaxo I think you misunderstood. I'm using the My point is that if I add A GTK event loop should surely prioritise GUI responsiveness over background work, but it seems the opposite is true. |
OK, I've dug into it a little more. Seems like I was wrong about After looking at some of the code, I've managed to create a function based off
Then adding an However, it doesn't work if you do a bare
So, when this yield happens which should return control to the event loop, it's not waiting till idle to run it again. If it was possible to have the event loop reschedule until idle when yielded, then users can do a simple |
So, I'm not sure how the previous issue could be fixed, as I don't understand how the Gio.Application.run() method works within Python. One other minor problem I see is the call_soon() method doesn't wait until idle, potentially resulting in some similar unresponsiveness. This is because the code changes the GLib.Idle priority. I see no reason for the priority to be changed (and even if that was the desired behaviour, why not use GLib.Timeout instead?). Removing this line would fix that minor issue: https://github.com/beeware/gbulb/blob/master/src/gbulb/glib_events.py#L865 |
I'm sorry, but I'm not maintaining gbulb anymore. I don't have time to work on it anymore due to my personal life. If you'd like to discuss ownership, please refer to #32. |
It seems to me your One little caveat is you need to keep a strong reference to the created task somewhere until it completes. I think I have something similar to what you are trying to do in my |
Actually I slipped up in that example, as This makes no difference, as the event loop will not update the widgets when you do a simple yield, as mentioned in my more recent comment: #44 (comment) So, doing |
Is it not updating widgets because there are no Gtk events pending ? |
I'm not sure what you mean, the only difference between the code is whether it Here's a complete reproducer. If you run this, you'll see a working progress bar. If you switch to one of the sleep 0 lines which are commented out, then you'll find the progress bar is not displayed/updated until the loop has completed.
|
@freakboy3742 I think this is more than just documentation. If you try out the previous program and switch between the different commented out methods, I believe all of them should work. But, currently doing I'm not familiar with the implementation, but I think that when yielded back to the event loop like this, GTK should complete all pending redraws/event handling before returning to other tasks. I'd also like to rehighlight #44 (comment) |
I'm completely lost as to how I would write await/async code within a Gtk Application. The example in the README is too short to be of any use, and those in
examples/
are also somewhat lacking and very out-of-date.Here's roughly what I have so far:
But, I can't use the
await update_things()
line, as the init function is not async. The closest thing I've been able to find, is changing that toasyncio.ensure_future(update_things())
, but the issue is that there doesn't seem to be a way to pause the current code like await does, in order to run theprogressbar.hide()
line after that coroutine has completed.I've also tried loop.run_until_complete() and similar functions, but it doesn't seem possible to run another coroutine that way either.
The text was updated successfully, but these errors were encountered: