asyncio - await coroutine more than once (periodic tasks)

喜你入骨 提交于 2020-08-08 05:23:05

问题


I am trying to create a periodic task for an asyncio event loop as shown below, however I am getting a "RuntimeError: cannot reuse already awaited coroutine" exception. Apparently, asyncio does not allow for the same awaitable function to be awaited as discussed in this bug thread. This is how I tried to implement it:

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

Because of my while loop, the same awaitable function (_async_func) would be executed with a sleep interval in between. I got my inspiration for the implementation of periodic tasks from How can I periodically execute a function with asyncio? .

From the bug thread mentioned above, I infer that the idea behind the RuntimeError was so that developers wouldn't accidentally await the same coroutine twice or more, as the coroutine would be marked as done and yield None instead of the result. Is there a way I can await the same function more than once?


回答1:


It seems you are confusing async functions (coroutine functions) with coroutines - values that these async functions produce.

Consider this async function:

async def sample():
    await asyncio.sleep(3.14)

You are passing result of its call: add_periodic_task(sample(), 5).

Instead, you should pass async function object itself: add_periodic_task(sample, 5), and call it within your wrapper:

while True:
    await _async_func()
    await asyncio.sleep(_interval)


来源:https://stackoverflow.com/questions/51116849/asyncio-await-coroutine-more-than-once-periodic-tasks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!