UPD:
如果你正在使用Python> = 3.7那就替换asyncio.ensure_future到asyncio.create_task任何地方它是更新,更好的方法来产生任务。
asyncio.Task“发射并忘记”
根据python文档,asyncio.Task可以启动一些协程来执行“在后台”。asyncio.ensure_future 函数创建的任务不会阻止执行(因此函数将立即返回!)。这看起来像你要求的“发射并忘记”的方式。
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()
# btw, you can also create tasks inside non-async funcs
print('Do some actions 1')
await asyncio.sleep(1)
print('Do some actions 2')
await asyncio.sleep(1)
print('Do some actions 3')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
输出:
Do some actions 1
async_foo started
Do some actions 2
async_foo done
Do some actions 3
如果在事件循环完成后执行任务怎么办?
请注意,asyncio期望任务将在事件循环完成时完成。所以如果你改成main():
async def main():
asyncio.ensure_future(async_foo()) # fire and forget
print('Do some actions 1')
await asyncio.sleep(0.1)
print('Do some actions 2')
程序结束后你会收到这个警告:
Task was destroyed but it is pending!
task:
为了防止您在事件循环完成后等待所有挂起的任务:
async def main():
asyncio.ensure_future(async_foo()) # fire and forget
print('Do some actions 1')
await asyncio.sleep(0.1)
print('Do some actions 2')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# Let's also finish all running tasks:
pending = asyncio.Task.all_tasks()
loop.run_until_complete(asyncio.gather(*pending))
杀死任务而不是等待它们
有时您不希望等待完成任务(例如,可能会创建一些任务以永久运行)。在这种情况下,你可以取消()而不是等待它们:
import asyncio
from contextlib import suppress
async def echo_forever():
while True:
print("echo")
await asyncio.sleep(1)
async def main():
asyncio.ensure_future(echo_forever()) # fire and forget
print('Do some actions 1')
await asyncio.sleep(1)
print('Do some actions 2')
await asyncio.sleep(1)
print('Do some actions 3')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# Let's also cancel all running tasks:
pending = asyncio.Task.all_tasks()
for task in pending:
task.cancel()
# Now we should await task to execute it's cancellation.
# Cancelled task raises asyncio.CancelledError that we can suppress:
with suppress(asyncio.CancelledError):
loop.run_until_complete(task)
输出:
Do some actions 1
echo
Do some actions 2
echo
Do some actions 3
echo