python - asyncio - 不止一次等待协程(周期性任务)

标签 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) 将在其间的 sleep 间隔内执行。我从 How can I periodically execute a function with asyncio? 中获得了执行周期性任务的灵感。 .

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

最佳答案

您似乎混淆了异步函数(协程函数)和协程 - 这些异步函数产生的值。

考虑这个异步函数:

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

您正在传递其调用的结果:add_periodic_task(sample(), 5)

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

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

关于python - asyncio - 不止一次等待协程(周期性任务),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51116849/

相关文章:

python - 使用 Pandas 命名 header

python - Azure 数据库摄取速度

java - 方法调用 Spring bean

python - 一种改变 asyncio 任务应该如何从调用 cancel() 的地方被取消的 Pythonic 方法

python - Ipywidgets 在交互式而不是小部件上观察方法

python - 具有可变数量 worker 的任务的最佳调度

java - 在 Spring 中实现调度程序

python - 如何处理 asyncio 中嵌套函数的 "This event loop is already running"错误?

task - Asyncio 在另一个任务中启动一个任务?

python匹配正则表达式