Asyncio任务未在asyncio.gather()中调用仍被执行如何解决?
问题根因
asyncio.create_task()的作用是将协程立即提交到当前事件循环的待执行队列,只要事件循环处于运行状态,所有已提交的任务都会被调度执行,和后续是否await该任务没有关系。你在预生成处理器字典时就为三个handler都执行了create_task,所以三个任务都会被触发运行。
实现方案
你不需要预先创建任务,只需要预先存储所有处理器的方法映射,仅在拿到需要执行的处理器参数后,再为指定处理器生成协程即可,不需要额外的取消操作。
修改后的代码示例
import asyncio class DataHandler(): def __init__(self): pass def generate_handler_map(self): # 仅存储处理器方法引用,不预先创建任务 all_handlers = { 'handler1': self.handler1, 'handler2': self.handler2, 'handler3': self.handler3, } return all_handlers async def main(self, handlers): print('Main method started') all_handlers = self.generate_handler_map() print('Handler coroutines created') # 仅为需要的处理器生成协程 required_coroutines = [] for handler in handlers: if handler in all_handlers: required_coroutines.append(all_handlers[handler]()) output = list(await asyncio.gather(*required_coroutines)) print(output) async def handler1(self): print('handler1 executed') return 'handler1_output' async def handler2(self): print('handler2 executed') return 'handler2_output' async def handler3(self): print('handler3 executed') return 'handler3_output' if __name__ == '__main__': dh = DataHandler() loop = asyncio.get_event_loop() loop.run_until_complete(dh.main(['handler2']))
运行输出
Main method started Handler coroutines created handler2 executed ['handler2_output']
补充说明
如果你确实有预先创建任务的强需求,无法做到按需创建,那么未使用的任务必须手动取消,没有其他方法可以阻止已提交到事件循环的任务被调度。
内容的提问来源于stack exchange,提问作者bilgehankosem
相关产品推荐
相关产品推荐

