[英]Asyncio tasks executed without being called in asyncio.gather()
I want to put some handler methods to a dictionary and call only some of them (based on the required handlers).我想将一些处理程序方法放入字典并仅调用其中一些(基于所需的处理程序)。 However, when the asyncio.gather() executed, all of the tasks are executed.但是,当执行 asyncio.gather() 时,所有任务都会执行。 Here is the code snippet:这是代码片段:
import asyncio
class DataHandler():
def __init__(self):
pass
async def generate_coroutines(self):
all_handlers = {
'handler1': asyncio.create_task(self.handler1()),
'handler2': asyncio.create_task(self.handler2()),
'handler3': asyncio.create_task(self.handler3()),
}
return all_handlers
async def main(self, handlers):
print('Main method started')
all_handlers = await self.generate_coroutines()
print('Handler coroutines created')
# Only add the handlers that has been given as the argument
required_handlers = []
for handler in handlers:
if handler in all_handlers.keys(): required_handlers.append(all_handlers[handler])
output = list(await asyncio.gather(*required_handlers))
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']))
Output: Output:
Main method started
Handler coroutines created
handler1 executed
handler2 executed
handler3 executed
['handler2_output']
Desired Output:所需 Output:
Main method started
Handler coroutines created
handler2 executed
['handler2_output']
If I cancel the unused tasks, then they are not executed.如果我取消未使用的任务,则不会执行它们。 But isn't it possible to create all the possible tasks and only execute some of them and let others go (without a need to cancel the rest)但是是不是可以创建所有可能的任务并只执行其中的一些任务并让其他任务执行 go(无需取消其余任务)
asyncio.create_task
creates Task
s that schedule the coroutines in an event loop. asyncio.create_task
创建在事件循环中安排协程的Task
。 You can fix this by delaying creating a coroutine and Task
:您可以通过延迟创建协程和Task
来解决此问题:
class DataHandler():
async def main(self, handlers):
print('Main method started')
# Only make coroutines from specified handlers
required_coroutines = []
for handler in handlers:
if hasattr(self, handler): # directly check instance for handler
required_coroutines.append(getattr(self, handler)())
print('Handler coroutines created')
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'
In your original code, the handler2()
coroutine didn't get scheduled a 2nd time by gather
because coroutines can't be scheduled more than once.在您的原始代码中, handler2()
协同程序没有被gather
第二次安排,因为协同程序不能被安排多次。 You have to call the async function each time and make a fresh coroutine.您必须每次调用异步 function 并创建一个新的协程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.