ข้อมูลจริง:
เริ่มจาก Python 3.7 asyncio.create_task(coro)ฟังก์ชันระดับสูงถูกเพิ่มเข้ามาเพื่อจุดประสงค์นี้
คุณควรใช้วิธีนี้แทนวิธีอื่นในการสร้างงานจาก coroutimes แต่ถ้าคุณต้องการที่จะสร้างงานจาก awaitable asyncio.ensure_future(obj)พลคุณควรใช้
ข้อมูลเก่า:
ensure_future เทียบกับ create_task
ensure_futureเป็นวิธีการที่จะสร้างจากTask coroutineสร้างงานในรูปแบบต่างๆตามอาร์กิวเมนต์ (รวมถึงการใช้create_taskสำหรับ coroutines และวัตถุในอนาคต)
create_taskAbstractEventLoopเป็นวิธีการที่เป็นนามธรรม ลูปเหตุการณ์ที่แตกต่างกันสามารถใช้ฟังก์ชันนี้ได้หลายวิธี
คุณควรใช้ensure_futureเพื่อสร้างงาน คุณจะต้องใช้create_taskก็ต่อเมื่อคุณจะใช้ประเภทเหตุการณ์วนซ้ำของคุณเอง
อัปเดต:
@ bj0 ชี้ไปที่คำตอบของ Guidoในหัวข้อนี้:
ประเด็นensure_future()คือถ้าคุณมีบางอย่างที่อาจเป็นโครูทีนหรือ a Future(อันหลังมี a Taskเพราะนั่นคือคลาสย่อยของFuture) และคุณต้องการที่จะสามารถเรียกใช้เมธอดบนมันที่กำหนดไว้เท่านั้นFuture(อาจเกี่ยวกับสิ่งเดียว เป็นตัวอย่างที่มีประโยชน์cancel()) เมื่อเป็นFuture(หรือTask) อยู่แล้วจะไม่ทำอะไรเลย เมื่อมันเป็นโครูทีนมันจะห่อด้วยTask.
ถ้าคุณรู้ว่าคุณมี coroutine และคุณต้องการที่จะกำหนดเวลา API create_task()ที่ถูกต้องในการใช้งาน เวลาเดียวที่คุณควรโทรensure_future()คือเมื่อคุณให้ API (เช่น API ส่วนใหญ่ของ asyncio เอง) ที่ยอมรับทั้งโครูทีนหรือ a Futureและคุณต้องทำบางอย่างกับมันที่คุณต้องมีFuture.
และหลังจากนั้น:
ในที่สุดฉันก็ยังเชื่อว่านั่นensure_future()เป็นชื่อที่คลุมเครืออย่างเหมาะสมสำหรับฟังก์ชันการทำงานที่ไม่ค่อยจำเป็น เมื่อมีการสร้างงานจาก coroutine
loop.create_task()ที่คุณควรใช้อย่างเหมาะสมชื่อ อาจจะมีนามแฝงว่า
asyncio.create_task()?
มันน่าแปลกใจสำหรับฉัน แรงจูงใจหลักของฉันที่จะใช้ensure_futureตลอดมาคือมันเป็นฟังก์ชั่นระดับสูงกว่าเมื่อเทียบกับสมาชิกวงcreate_task(การสนทนามีแนวคิดบางอย่างเช่นการเพิ่มasyncio.spawnหรือasyncio.create_task)
ฉันยังสามารถชี้ให้เห็นว่าในความคิดของฉันมันค่อนข้างสะดวกที่จะใช้ฟังก์ชันสากลที่สามารถจัดการได้Awaitableมากกว่าโครูทีนเท่านั้น
อย่างไรก็ตามคำตอบของ Guido นั้นชัดเจน: "เมื่อสร้างงานจาก coroutine คุณควรใช้ชื่อที่เหมาะสมloop.create_task()"
เมื่อใดควรห่อโครูทีนในงาน?
ห่อโครูทีนในงาน - เป็นวิธีเริ่มโครูทีนนี้ "ในพื้นหลัง" นี่คือตัวอย่าง:
import asyncio
async def msg(text):
await asyncio.sleep(0.1)
print(text)
async def long_operation():
print('long_operation started')
await asyncio.sleep(3)
print('long_operation finished')
async def main():
await msg('first')
task = asyncio.ensure_future(long_operation())
await msg('second')
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
เอาท์พุต:
first
long_operation started
second
long_operation finished
คุณสามารถแทนที่asyncio.ensure_future(long_operation())ด้วยเพียงawait long_operation()เพื่อให้รู้สึกถึงความแตกต่าง
create_taskหากคุณต้องการวัตถุงานจริงๆซึ่งโดยปกติคุณไม่ควรต้องการ: github.com/python/asyncio/issues/477#issuecomment-268709555