0

所以我开始我的程序是这样的:

    try: b.loop.call_soon_threadsafe(b.loop.run_in_executor, None, lambda: trio.run(wallpaper))
    except BaseException as e:
        sys.exit(e)
    try:
        b.loop.run_until_complete(background_task())
    except (KeyboardInterrupt,SystemExit,RuntimeError):
        try: b.loop.close()
        except BaseException: os._exit(0) # I have to do this or else the program will never close as asyncio will raise a RuntimeError indicating the loop is already closed. The `try` block might as well not exist cause it never works anyway.

trio 协程函数的开头是这样的:

sp = Sleeper() 

async def wallpaper() -> typing.NoReturn:

    with trio.CancelScope() as scope:
        async with trio.open_nursery() as nursery:
            nursery.start_soon(sp.sleep_handler)
            await nursery.start(sp.watchdog)
            await sp.nursery_closed()
            scope.cancel()

这是那个类:

class Sleeper:

    _end = trio.Event()

    def __init__(this, *args, **kwds):
        # some variables

    @classmethod
    def set_end(cls):
        cls._end.set()

    @classmethod
    async def nursery_closed(cls):

        await cls._end.wait()

    @classmethod
    def scope_canceled(cls):

        return cls._end.is_set()

    async def watchdog(this, task_status=trio.TASK_STATUS_IGNORED):
        task_status.started()
        while True:
            await trio.sleep(5)
            if b.is_closed(): # `b` is a class instance running in asyncio.
                this.set_end()
                break
        """# I can't use this outside of the main thread unfortunately, so I am trying the above instead.
        with trio.open_signal_receiver(signal.SIGINT) as watcher:
            task_status.started()
            async for signum in watcher:
                assert signum == signal.SIGINT
                this.set_end()
        """
    async def sleep_handler(this) -> typing.NoReturn:
        if not this.scope_ready():
            await this.nursery_spawned() # I didn't include it here but this is the same as below, but to indicate when it's ready rather than closed.
        while not this.scope_canceled():
            pass # stuff that is always running and never returning

我曾经能够结束程序,b.loop.close但在三重奏运行时,它永远无法执行并引发 RuntimeError 将我的程序陷入某个无限循环,甚至在我关闭 powershell 窗口时都不会停止,这需要我从任务管理器。这已经解决了,os_exit()但感觉就像我在躲避这个问题而不是纠正它。除非我大大修改了我正在使用的与 asyncio 一起运行的库,否则代码的 asyncio 部分大部分都无法更改。退出有什么大的缺点os._exit(0)吗?有没有更好的方法让 Trio 和 Asyncio 一起运行?我想继续使用 Trio。

4

0 回答 0