asyncio-多次等待协程(定期任务)

时间:2018-06-30 16:55:46

标签: python scheduled-tasks python-asyncio periodic-task

我试图为asyncio事件循环创建一个定期任务,如下所示,但是我遇到了“ RuntimeError:无法重用已经等待的协程”异常。显然,asyncio不允许等待this bug thread中讨论的相同的等待功能。这是我尝试实现的方法:

import asyncio    

class AsyncEventLoop:    

    def __init__(self):
        self._loop = asyncio.get_event_loop()

    def add_periodic_task(self, async_func, interval):
        async def wrapper(_async_func, _interval):
            while True:
                await _async_func               # This is where it goes wrong
                await asyncio.sleep(_interval)
        self._loop.create_task(wrapper(async_func, interval))
        return

    def start(self):
        self._loop.run_forever()
        return

由于我的while循环,相同的等待函数(_async_func)将在它们之间的睡眠间隔内执行。我从How can I periodically execute a function with asyncio? 获得了执行定期任务的灵感。

从上面提到的错误线程中,我推断RuntimeError背后的想法是,使开发人员不会意外地等待相同的协程两次或两次以上,因为协程将被标记为完成并产生None而不是结果。有没有办法我可以多次等待相同的功能?

1 个答案:

答案 0 :(得分:4)

似乎您正在将异步函数(协程函数)与协程(这些异步函数产生的值)混淆。

考虑此异步功能:

canvas.toBlob(blob => upload(blob), 'image/jpeg', 1.0)

您正在传递呼叫结果:async def sample(): await asyncio.sleep(3.14)

相反,您应该传递异步函数对象本身:add_periodic_task(sample(), 5),并在包装​​器中调用它:

add_periodic_task(sample, 5)