tbraun89
tbraun89

Reputation: 2234

Python 3 with asyncio tasks not executed when returned in a generator function

This first example does not work, I try to emit an async task but don't care about the response in that situation, output is empty:

from typing import Iterable
import asyncio

async def example_task():
    print('example_task')

def emit() -> Iterable:
    event_loop = asyncio.get_event_loop()
    yield event_loop.create_task(example_task())

async def main():
    emit()
    await asyncio.sleep(0.5) # wait some time so the task can run

asyncio.run(main())

When I add next(emit()) to actually "read" the yielded task the output works and also in the next example it works when I put all the task into a list first:

from typing import Iterable
import asyncio

async def example_task():
    print('example_task')

def emit() -> Iterable:
    event_loop = asyncio.get_event_loop()
    return iter([event_loop.create_task(example_task())]) 

async def main():
    emit()
    await asyncio.sleep(0.5) # wait some time so the task can run

asyncio.run(main())

This is just a simple example, the final version should be able to emit an "event" and run 1..n async tasks that can return a value but don't need to. The caller of emit should be able to decide if he awaits the result at some point or just ignore it like in the examples.

Is there any way I can do this with a generator / yield or is the only possible way to store all the tasks in a list and return an iterator after that?

Upvotes: 0

Views: 372

Answers (1)

JRajan
JRajan

Reputation: 702

The issue is that you are returning a generator with the first example where the second example has the task object which needs to be executed.

The modified version of your first example would be something like

async def main():
    next(emit())
    await asyncio.sleep(0.5) # wait some time so the task can run

or

async def main():
    for task in emit():
        await task
        await asyncio.sleep(0.5) # wait some time so the task can run

Hope this explains the difference between using a generator and a iterator while creating your tasks.

Upvotes: 1

Related Questions