Thông tin thực tế:
Bắt đầu từ Python 3.7, asyncio.create_task(coro)hàm cấp cao đã được thêm vào cho mục đích này.
Bạn nên sử dụng nó thay vì các cách khác để tạo nhiệm vụ từ thời gian đăng quang. Tuy nhiên, nếu bạn cần tạo tác vụ từ chờ tùy ý, bạn nên sử dụng asyncio.ensure_future(obj).
Thông tin cũ:
ensure_future vs create_task
ensure_futurelà một phương pháp để tạo Tasktừ coroutine. Nó tạo ra các tác vụ theo những cách khác nhau dựa trên đối số (bao gồm cả việc sử dụng create_taskfor coroutines và các đối tượng tương lai).
create_tasklà một phương pháp trừu tượng của AbstractEventLoop. Các vòng lặp sự kiện khác nhau có thể triển khai chức năng này theo những cách khác nhau.
Bạn nên sử dụng ensure_futuređể tạo nhiệm vụ. Bạn create_taskchỉ cần thực hiện loại vòng lặp sự kiện của riêng mình.
Cập nhật:
@ bj0 đã chỉ vào câu trả lời của Guido về chủ đề này:
Vấn đề ensure_future()là nếu bạn có một cái gì đó có thể là một quy trình đăng quang hoặc một Future(cái sau bao gồm một Taskvì đó là một lớp con của Future) và bạn muốn có thể gọi một phương thức trên đó chỉ được xác định trên Future(có thể là về ví dụ hữu ích đang cancel()). Khi nó đã là một Future(hoặc Task) điều này không làm gì cả; khi nó là một quy trình, nó sẽ bao bọc nó trong một Task.
Nếu bạn biết rằng bạn có một quy trình đăng ký và bạn muốn nó được lên lịch, thì API chính xác để sử dụng là create_task(). Thời điểm duy nhất khi bạn nên gọi ensure_future()là khi bạn đang cung cấp một API (giống như hầu hết các API riêng của asyncio) chấp nhận một quy trình đăng ký hoặc một quy trình đăng ký Futurevà bạn cần phải làm gì đó với nó mà yêu cầu bạn phải có Future.
và sau đó:
Cuối cùng, tôi vẫn tin rằng đó ensure_future()là một cái tên ít người biết đến cho một phần chức năng hiếm khi cần thiết. Khi tạo một nhiệm vụ từ một quy trình đăng ký, bạn nên sử dụng tên thích hợp
loop.create_task(). Có lẽ nên có một bí danh cho điều đó
asyncio.create_task()?
Thật là ngạc nhiên đối với tôi. Động lực chính của tôi khi sử dụng ensure_futuretất cả là chức năng cấp cao hơn của nó so với thành viên của vòng lặp create_task(thảo luận chứa một số ý tưởng như thêm asyncio.spawnhoặc asyncio.create_task).
Tôi cũng có thể chỉ ra rằng theo ý kiến của tôi, khá tiện lợi khi sử dụng hàm phổ quát có thể xử lý bất kỳ Awaitablethay vì chỉ coroutines.
Tuy nhiên, câu trả lời của Guido rất rõ ràng: "Khi tạo một nhiệm vụ từ một chương trình điều tra, bạn nên sử dụng tên phù hợp loop.create_task()"
Khi nào coroutines nên được gói trong các nhiệm vụ?
Kết thúc quy trình đăng ký trong một Nhiệm vụ - là một cách để bắt đầu quy trình đăng ký này "trong nền". Đây là ví dụ:
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')
# Now you want to start long_operation, but you don't want to wait it finised:
# long_operation should be started, but second msg should be printed immediately.
# Create task to do so:
task = asyncio.ensure_future(long_operation())
await msg('second')
# Now, when you want, you can await task finised:
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Đầu ra:
first
long_operation started
second
long_operation finished
Bạn có thể thay thế asyncio.ensure_future(long_operation())bằng chỉ await long_operation()để cảm nhận sự khác biệt.
create_tasknếu bạn thực sự cần aa đối tượng nhiệm vụ, mà bạn thường không cần: github.com/python/asyncio/issues/477#issuecomment-268709555