user8245289
user8245289

Reputation: 303

Asyncio, await and infinite loops

async def start(channel):
    while True:
        m = await client.send_message(channel, "Generating... ")
        generator.makeFile()
        with open('tmp.png', 'rb') as f:
            await client.send_file(channel, f) 
        await client.delete_message(m)
        await asyncio.sleep(2)

I have a discord bot that runs a task every 2 seconds. I tried using an infinite loop for this, but the script crashes with a Task was destroyed but it is still pending! I have read about asyncio's coroutines, but none of the examples that I found use await in them. Is it possible avoid this error, by running a coroutine with await, for example?

Upvotes: 20

Views: 30332

Answers (1)

Mikhail Gerasimov
Mikhail Gerasimov

Reputation: 39516

Task was destroyed but it is still pending! is warning that you receive when you call loop.close() when some of tasks in your script aren't finished. Usually you should avoid this situation because unfinished task may not release some resources. You need either to await task done or cancel it before event loop closed.

Since you have infinite loop you probably would need to cancel task, example:

import asyncio
from contextlib import suppress


async def start():
    # your infinite loop here, for example:
    while True:
        print('echo')
        await asyncio.sleep(1)


async def main():
    task = asyncio.Task(start())

    # let script some thime to work:
    await asyncio.sleep(3)

    # cancel task to avoid warning:
    task.cancel()
    with suppress(asyncio.CancelledError):
        await task  # await for task cancellation


loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(main())
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()

See also this answer for more information about tasks.

Upvotes: 14

Related Questions