Asynchronous programming in Python often involves tasks that do not require immediate attention. One approach to handle such tasks is to use the "fire and forget" pattern, which allows a task to run concurrently without blocking the main execution flow.
In Tornado's coroutine implementation, this pattern could be achieved by omitting the yield keyword. However, in Python 3.5 onward, async/await syntax requires a different approach.
According to the Python documentation for asyncio.Task, coroutines can be executed "in the background" by using asyncio.ensure_future to create a task. This task will run concurrently without blocking the function.
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() # ... Other code can be executed here ...
By default, asyncio expects tasks to be completed before the event loop completes. If tasks are still running after the event loop has completed, a warning will be issued. To avoid this warning, all pending tasks should be awaited after the event loop has completed.
loop = asyncio.get_event_loop() loop.run_until_complete(main()) # Wait for any remaining tasks pending = asyncio.Task.all_tasks() await asyncio.gather(*pending)
In some cases, tasks may need to be cancelled instead of awaited. This can be done using task.cancel(), but the cancelled task needs to be awaited to complete its cancellation.
# ... Same code as before ... # Cancel all running tasks pending = asyncio.Task.all_tasks() for task in pending: task.cancel() with suppress(asyncio.CancelledError): await asyncio.wait_for(task, timeout=None)
The above is the detailed content of How Can You Implement 'Fire and Forget' with Python's Async/Await?. For more information, please follow other related articles on the PHP Chinese website!