7.1 Tworzenie zadań
Klasa Task
w module asyncio jest używana do zarządzania wykonaniem korutyn. Zadania (Tasks)
to opakowania dla korutyn, umożliwiające kontrolowanie ich wykonania i monitorowanie ich stanu. Klasa Task
pozwala na równoległe uruchamianie korutyn, zarządzając nimi za pomocą pętli zdarzeń.
Podstawowe metody klasy Task
Klasa Task
to swego rodzaju opakowanie wokół korutyny, które daje dodatkowe możliwości takie jak:
Zarządzanie wykonaniem korutyn:
Zadania umożliwiają łatwe zarządzanie wykonaniem korutyn, kontrolowanie ich stanu oraz uzyskiwanie wyników.
Anulowanie zadań:
Możliwość anulowania zadań czyni Task
użytecznym do zarządzania długotrwałymi operacjami, które mogą wymagać zatrzymania przed zakończeniem.
Wywołania zwrotne:
Zadania obsługują dodawanie wywołań zwrotnych, co pozwala na wykonywanie dodatkowych działań po zakończeniu zadań.
Tworzenie zadań:
Zadania są tworzone za pomocą funkcji asyncio.create_task(coroutine)
lub metody loop.create_task(coroutine)
, które planują wykonanie korutyny.
import asyncio
async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
7.2 Podstawowe metody
Metoda Task.cancel()
:
Żąda anulowania zadania. Jeśli zadanie nie zostało jeszcze zakończone, zostanie zakończone wywołaniem wyjątku CancelledError
.
Napiszmy mały program, który pozwoli nam to zademonstrować.
Utwórzmy asynchroniczne zadanie, które będzie po prostu czekać 10 sekund
Opakujmy je w obiekt
Task
Poczekajmy sekundę, aby zadanie (Task) zaczęło się wykonywać
Anulujmy zadanie –
task.cancel()
-
Jeśli później spróbujemy poczekać na zakończenie zadania (Task) przy pomocy operatora
await
, to otrzymamy wyjątekCancelledError
.
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(10))
await asyncio.sleep(1)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Task was cancelled")
asyncio.run(main())
Metoda Task.result()
:
Zwraca wynik wykonania zadania. Jeśli zadanie zakończyło się wyjątkiem, zostanie wywołane przy wywołaniu result()
.
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(1, result='Completed'))
result = await task
print(result) # Output: Completed
asyncio.run(main())
W naszym przypadku nie musieliśmy pisać dodatkowego kodu — operator await
rozumie, jak pracować z obiektem Task
: po wykonaniu zadania sam wywoła u niego metodę result()
i zwróci uzyskany wynik.
Metoda Task.exception()
:
Zwraca wyjątek, który zadanie wywołało. Jeśli zadanie zakończyło się bez wyjątku, zwraca None
.
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(1))
try:
result = await task
except Exception as e:
print(f"Task failed with exception: {e}")
asyncio.run(main())
Dodatkowy kod również nie jest potrzebny — jeśli w zadaniu pojawił się wyjątek, metoda exception()
zostanie wywołana przez operator await
.
Metoda Task.add_done_callback(callback)
:
Dodaje wywołanie zwrotne (callback)
, które zostanie wywołane po zakończeniu zadania.
import asyncio
def callback(future):
print("Task completed")
async def main():
task = asyncio.create_task(asyncio.sleep(1))
task.add_done_callback(callback)
await task
asyncio.run(main())
Do zadania można dodać funkcję, która zostanie automatycznie wywołana, gdy zadanie zakończy wykonywanie. Takie podejście pozwala na uczynienie kodu bardzo elastycznym. Co więcej, można dodać kilka funkcji i dodawać je do dowolnych zadań.
Metoda Task.done()
:
Zwraca True
, jeśli zadanie zostało zakończone (z sukcesem, z błędem lub zostało anulowane).
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(1))
await asyncio.sleep(1.5)
print(task.done()) # Output: True
asyncio.run(main())
Za pomocą metody done()
można sprawdzić, czy zadanie zostało pomyślnie wykonane. A dokładniej, czy zostało wykonane lub anulowane, ponieważ jeśli wystąpił wyjątek, to formalnie zadanie może być i nie wykonane, ale także nie było anulowane. W skrócie, jeśli zadanie zostało anulowane (cancel)
, to metoda zwróci False
, w przeciwnym razie zwróci True
.
GO TO FULL VERSION