您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python使用asyncio異步時的常見問題有哪些”,在日常操作中,相信很多人在Python使用asyncio異步時的常見問題有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python使用asyncio異步時的常見問題有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
我們可以通過 asyncio.Task 對象上的 cancel() 方法取消任務。如果任務被取消,cancel() 方法返回 True,否則返回 False。
... # cancel the task was_cancelled = task.cancel()
如果任務已經完成,則無法取消,cancel() 方法將返回 False,任務不會處于已取消狀態。
下次任務有機會運行時,它將引發 CancelledError 異常。如果 CancelledError 異常未在包裝協程內處理,任務將被取消。
否則,如果在包裝協程內處理了 CancelledError 異常,任務將不會被取消。cancel() 方法還可以接受一個消息參數,該參數將在 CancelledError 的內容中使用。
我們可以探索如何取消正在運行的任務。
在這個例子中,我們定義了一個任務協程,它報告一條消息然后阻塞片刻。
然后我們定義用作 asyncio 程序入口點的主協程。它報告一條消息,創建并安排任務,然后等待片刻。
然后主協程在運行時恢復和取消任務。它再等一會兒,讓任務響應取消請求。然后主協程報告取消任務的請求是否成功。
任務被取消,然后完成。主協程然后在關閉程序之前報告任務的狀態是否已取消。
# SuperFastPython.com # example of canceling a running task import asyncio # define a coroutine for a task async def task_coroutine(): # report a message print('executing the task') # block for a moment await asyncio.sleep(1) # custom coroutine async def main(): # report a message print('main coroutine started') # create and schedule the task task = asyncio.create_task(task_coroutine()) # wait a moment await asyncio.sleep(0.1) # cancel the task was_cancelled = task.cancel() # report whether the cancel request was successful print(f'was canceled: {was_cancelled}') # wait a moment await asyncio.sleep(0.1) # check the status of the task print(f'canceled: {task.cancelled()}') # report a final message print('main coroutine done') # start the asyncio program asyncio.run(main())
運行該示例會啟動 asyncio 事件循環并執行 main() 協程。main() 協程報告一條消息,然后創建并調度任務協程。然后它暫停并等待片刻以允許任務協程開始運行。任務運行,報告消息并休眠一段時間。
main() 協程恢復和取消任務。它報告取消任務的請求已成功。然后它會休眠片刻,讓任務響應要取消的請求。
task_coroutine() 恢復并引發 CancelledError 異常,導致任務失敗并完成。main()協程恢復并報告任務是否處于取消狀態。在這種情況下,確實如此。
此示例突出顯示了取消正在運行的任務的正常情況。
main coroutine started
executing the task
was canceled: True
canceled: True
main coroutine done
我們可以通過直接等待 asyncio.Task 對象來等待任務完成。
... # wait for the task to finish await task
我們可以在一行中創建和等待任務。
... # create and wait for the task to finish await asyncio.create_task(custom_coro())
我們可能需要將協程的值返回給調用者。我們可以通過等待從協程中檢索返回值。它假定正在等待的另一個協程返回一個值。
# coroutine that returns a value async def other_coro(): return 100
等待其他協程將掛起調用協程并安排其他協程執行。一旦另一個協程完成,調用協程將恢復。返回值將從另一個協程傳遞給調用者。
... # execute coroutine and retrieve return value value = await other_coro()
協程可以包裝在 asyncio.Task 對象中。這有助于獨立執行協程而無需當前協程等待它。
這可以使用 asyncio.create_task() 函數來實現。
... # wrap coroutine in a task and schedule it for execution task = asyncio.create_task(other_coro())
有兩種方法可以從 asyncio.Task 中檢索返回值,它們是:
等待任務。
調用結果() 方法。
我們可以等待任務來檢索返回值。如果任務已安排或正在運行,則調用者將掛起,直到任務完成并提供返回值。如果任務完成,將立即提供返回值。
... # get the return value from a task value = await task
與協程不同,我們可以多次等待任務而不會引發錯誤。
... # get the return value from a task value = await task # get the return value from a task value = await task
我們還可以通過調用 asyncio.Task 對象的 result() 方法來獲取任務的返回值。
... # get the return value from a task value = task.result()
這需要完成任務。如果不是,將引發 InvalidStateError 異常。如果任務被取消,將引發 CancelledError 異常。
我們可以通過將協程包裝在 asyncio.Task 對象中來在后臺運行協程。這可以通過調用 asyncio.create_task() 函數并將其傳遞給協程來實現。
協程將被包裝在一個 Task 對象中,并被安排執行。將返回任務對象,調用者不會掛起。
... # schedule the task for execution task = asyncio.create_task(other_coroutine())
至少在當前協程出于任何原因掛起之前,任務不會開始執行。我們可以通過暫停片刻讓任務開始運行來幫助解決問題。這可以通過休眠零秒來實現。
... # suspend for a moment to allow the task to start running await asyncio.sleep(0)
這將暫停調用者一小會兒,并允許請求運行的機會。這不是必需的,因為調用者可能會在未來某個時間暫停或作為正常執行的一部分終止。一旦調用者沒有事情要做,我們也可以直接等待任務。
... # wait for the task to complete await task
我們可以等待 asyncio 程序中的所有獨立任務。這可以通過首先通過 asyncio.all_tasks() 函數獲取一組所有當前正在運行的任務來實現。
... # get a set of all running tasks all_tasks = asyncio.all_tasks()
這將返回一個集合,其中包含一個 asyncio.Task 對象,用于當前正在運行的每個任務,包括 main() 協程。
我們不能直接等待這個集合,因為它會永遠阻塞,因為它包含當前任務。因此,我們可以獲取當前正在運行的任務的 asyncio.Task 對象并將其從集合中刪除。
這可以通過首先調用 asyncio.current_task() 方法來獲取當前協程的任務,然后通過 remove() 方法將其從集合中刪除來實現。
... # get the current tasks current_task = asyncio.current_task() # remove the current task from the list of all tasks all_tasks.remove(current_task)
最后,我們可以等待剩余的任務集。這將掛起調用者,直到集合中的所有任務都完成。
... # suspend until all tasks are completed await asyncio.wait(all_tasks)
將它們結合在一起,下面添加到 main() 協程末尾的代碼片段將等待所有后臺任務完成。
... # get a set of all running tasks all_tasks = asyncio.all_tasks() # get the current tasks current_task = asyncio.current_task() # remove the current task from the list of all tasks all_tasks.remove(current_task) # suspend until all tasks are completed await asyncio.wait(all_tasks)
到此,關于“Python使用asyncio異步時的常見問題有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。