Cập nhật:
Thay thế asyncio.ensure_future
bằng asyncio.create_task
mọi nơi nếu bạn đang sử dụng Python> = 3.7 Đây là cách mới hơn, đẹp hơn để tạo tác vụ .
asyncio.Task để "chữa cháy và quên đi"
Theo tài liệu python asyncio.Task
, có thể bắt đầu một số quy trình đăng ký để thực thi "trong nền" . Tác vụ được tạo bởi asyncio.ensure_future
hàm sẽ không chặn việc thực thi (do đó hàm sẽ trả về ngay lập tức!). Đây có vẻ như là một cách để "bắn và quên" như bạn đã yêu cầu.
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())
Đầu ra:
Do some actions 1
async_foo started
Do some actions 2
async_foo done
Do some actions 3
Điều gì sẽ xảy ra nếu các tác vụ đang thực thi sau khi vòng lặp sự kiện hoàn tất?
Lưu ý rằng asyncio dự kiến nhiệm vụ sẽ được hoàn thành tại thời điểm hoàn thành vòng lặp sự kiện. Vì vậy, nếu bạn sẽ thay đổi main()
thành:
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')
Bạn sẽ nhận được cảnh báo này sau khi chương trình kết thúc:
Task was destroyed but it is pending!
task: <Task pending coro=<async_foo() running at [...]
Để tránh điều đó, bạn chỉ có thể đợi tất cả các nhiệm vụ đang chờ xử lý sau khi hoàn thành vòng lặp sự kiện:
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))
Giết nhiệm vụ thay vì chờ đợi chúng
Đôi khi bạn không muốn đợi các tác vụ được thực hiện (ví dụ: một số tác vụ có thể được tạo để chạy mãi mãi). Trong trường hợp đó, bạn chỉ có thể hủy () chúng thay vì chờ chúng:
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)
Đầu ra:
Do some actions 1
echo
Do some actions 2
echo
Do some actions 3
echo