Python 如果其中一个任务在异步IO中完成,如何关闭循环

Python 如果其中一个任务在异步IO中完成,如何关闭循环,python,python-3.x,python-asyncio,Python,Python 3.x,Python Asyncio,我有三项任务- def task_a(): while True: file.write() asyncio.sleep(10) def task_b(): while True: file.write() asyncio.sleep(10) def task_c(): # do something main.py- try: loop = asyncio.get_event_loop()

我有三项任务-

def task_a(): 
    while True:
        file.write()
        asyncio.sleep(10)

def task_b():
    while True:
        file.write()
        asyncio.sleep(10)


def task_c():
    # do something
main.py-

try:
    loop = asyncio.get_event_loop()
    A = loop.create_task(task_a)
    B = loop.create_task(task_b)
    C = loop.create_task(task_c)

    awaitable_pending_tasks = asyncio.all_tasks()
    execution_group = asyncio.gather(*awaitable_pending_tasks, return_exceptions=True)
        fi_execution = loop.run_until_complete(execution_group)
finally:
    loop.run_forever()
我想确保在任务完成时退出循环。 最后尝试在中使用loop.close(),但由于它是异步的,所以在两者之间关闭

task_a和task_b写入文件,并且正在运行另一个进程来检查文件的修改时间。如果它大于一分钟,则会导致错误(我不希望这样),因此我将while循环放入其中,并在写入后添加一个sleep()

一旦任务完成,我需要停止循环

关于StackOverflow的其他答案看起来很难理解。
有什么办法可以做到吗?

您可以调用
循环。运行_直到_完成
异步。运行
(但不是
永远运行
),运行一个函数来准备您需要的任务,然后只等待
您想要终止循环的任务(未测试):


解决方案确实执行task_c,但在执行asyncio.gather跟踪-if child.cancel()时遇到了问题:\n[上一行重复了491次]\n File\“/usr/local/lib/python3.8/asyncio/tasks.py\”,第711行,在cancel\n if self.done()中:\n解释错误:调用Python对象时超过了最大递归深度,“exc_text”:null,“stack_info:null,“lineno”:51}我通过将循环传递给task_c并在task_c结束时停止循环来处理此情况。我知道这实际上是一种不好的方式,因为我正在关闭方法中的循环。也许你应该从你取消的任务集中排除
asyncio.current_task()
。早些时候,我已经删除了wait asyncio.gather(*tasks,return_exceptions=True)并处理了asyncio.exceptions.CancelledError,但从任务中删除当前任务解决了它。感谢asyncio king@user4815162342:)我可以更深入地学习asyncio的任何资源吗?你能解释一下在asyncio之后做了什么吗。创建_任务(任务A)asyncio.create_任务(任务b)@Arjunsingh正确。请注意,
asyncio.gather()
只是一个方便的函数,用于等待任务和(在被请求时)抑制异常,这里只需要避免一个恼人的警告。您可以在循环中等待它们,并将每个等待包装在
suppress(cancelederror)
中,但这将是更多的代码。@Arjunsingh可能是一个好的函数。
async def main():
    asyncio.create_task(task_a)
    asyncio.create_task(task_b)
    await task_c
    tasks = set(asyncio.all_tasks()) - set([asyncio.current_task()])
    for t in tasks:
        t.cancel()
    await asyncio.gather(*tasks, return_exceptions=True)

asyncio.run(main())
# or asyncio.get_event_loop().run_until_complete(main())