Tips

Dealing with Cancellation

When an asyncgui.Task instance is being cancelled, a asyncgui.Cancelled exception is raised inside it. You can take advantage of this to perform cleanup or other actions, like so:

async def async_func():
    try:
        ...
    except Cancelled:
        something_you_want_to_do_only_when_cancelled()
        raise  # You must re-raise !!
    finally:
        cleanup_resources()

You are not allowed to ‘await’ anything inside an except-Cancelled-clause and a finally-clause because cancellations always must be handled immediately in asyncgui.

async def async_func():
    try:
        await something  # <-- ALLOWED
    except Exception:
        await something  # <-- ALLOWED
    except Cancelled:
        await something  # <-- NOT ALLOWED
        raise
    finally:
        await something  # <-- NOT ALLOWED

This includes async for and async with as they ‘await’ __aiter__(), __anext__(), __aenter__() and __aexit__().

xxx ignored GeneratorExit

This error likely means that you forgot to cancel a root task, and it ended up being garbage-collected while still running— which is not desirable in asyncgui.

Make sure to explicitly cancel the task to avoid this!

Coexistence with other async libraries

asyncio and trio do some hacky stuff, sys.set_asyncgen_hooks() and sys.get_asyncgen_hooks(), which likely delays the cleanup of async generators when either of these libraries is running. You can see its details here.

Because of this, you have to explicitly close async generators when you are done with them.