In certain scenarios, there is a need to initiate an asynchronous operation that doesn't require waiting for its completion. Traditionally, the "fire and forget" approach in Tornado's coroutines could be achieved by omitting the yield keyword.
In Python 3.5's async/await syntax, however, such an implementation raises a RuntimeWarning, indicating that the coroutine was never awaited.
Fortunately, Python's asyncio library provides a solution through its asyncio.Task class. This allows the creation of a task that can execute in the background, without blocking the main execution.
import asyncio async def async_foo(): print("async_foo started") await asyncio.sleep(1) print("async_foo done") async def main(): asyncio.ensure_future(async_foo()) # fire and forget async_foo() # continue with other actions if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(main())
This approach ensures that async_foo() is executed asynchronously while other actions can continue without waiting.
It's important to note that when the event loop completes, asyncio expects all tasks to be finished. As such, any remaining pending tasks can result in warnings. To prevent this, one can either await all pending tasks or cancel them.
Option 1: Await Pending Tasks
pending = asyncio.Task.all_tasks() loop.run_until_complete(asyncio.gather(*pending))
Option 2: Cancel Pending Tasks
pending = asyncio.Task.all_tasks() for task in pending: task.cancel() with suppress(asyncio.CancelledError): loop.run_until_complete(task)
By canceling the tasks, they are removed from the event loop's schedule, preventing any potential warnings.
The above is the detailed content of How to Implement 'Fire and Forget' Asynchronous Operations in Python Async/Await?. For more information, please follow other related articles on the PHP Chinese website!