简体   繁体   English

在 asyncio.gather() 中未调用的情况下执行的 Asyncio 任务

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM