UPD:
แทนที่asyncio.ensure_future
ด้วยasyncio.create_task
ทุกที่ถ้าคุณกำลังใช้งูหลาม> = 3.7 มันใหม่วิธีที่ดีกว่าให้กับงานวางไข่
asyncio ภารกิจ "ยิงและลืม"
ตามเอกสารหลามสำหรับasyncio.Task
มันเป็นไปได้ที่จะเริ่มต้น coroutine บางอย่างที่จะดำเนินการ "ในพื้นหลัง" งานที่สร้างโดย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: <Task pending coro=<async_foo() running at [...]
เพื่อป้องกันไม่ให้คุณสามารถรองานที่รอดำเนินการทั้งหมดหลังจากเสร็จสิ้นการวนซ้ำเหตุการณ์:
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