7.1 Creazione di Task
La classe Task
nel modulo asyncio è usata per gestire l'esecuzione
delle coroutine. I task (Tasks)
sono dei wrapper per le coroutine,
che permettono di gestire la loro esecuzione e monitorare il loro stato.
La classe Task
consente di eseguire le coroutine in parallelo, gestendole
attraverso il ciclo di eventi.
Metodi principali della classe Task
La classe Task
è un certo wrapper attorno a una coroutine, che offre
le seguenti funzionalità aggiuntive:
Gestione dell'esecuzione delle coroutine:
I task consentono di gestire facilmente l'esecuzione delle coroutine, controllare il loro stato e ottenere risultati.
Cancellazione dei task:
La possibilità di cancellare i task rende Task
utile per gestire
operazioni prolungate che potrebbero richiedere un'interruzione prima
del completamento.
Callback:
I task supportano l'aggiunta di callback, che consentono di eseguire azioni aggiuntive al completamento dei task.
Creazione di task:
I task vengono creati utilizzando la funzione
asyncio.create_task(coroutine)
o il metodo
loop.create_task(coroutine)
, che pianificano
l'esecuzione della coroutine.
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 Metodi Principali
Metodo Task.cancel()
:
Richiede la cancellazione del task. Se il task non è ancora terminato, sarà
terminato con il lancio di un'eccezione CancelledError
.
Scriviamo un piccolo programma per dimostrarlo.
Creiamo un task asincrono che aspetterà per 10 secondi
Lo avvolgiamo in un oggetto
Task
Aspettiamo un secondo affinché il task inizi l'esecuzione
Cancelliamo il task –
task.cancel()
-
Se poi tentiamo di attendere il completamento del task usando l'operatore
await
, otterremo un'eccezioneCancelledError
.
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())
Metodo Task.result()
:
Restituisce il risultato dell'esecuzione del task. Se il task è terminato con
un'eccezione, sarà lanciata al richiamo di 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())
Nel nostro caso non è nemmeno necessario scrivere codice aggiuntivo — l'operatore
await
capisce come lavorare con l'oggetto Task
: dopo il completamento del task
chiamerà automaticamente il metodo result()
e restituirà il risultato ottenuto.
Metodo Task.exception()
:
Restituisce l'eccezione sollevata dal task. Se il task è terminato
senza eccezioni, restituisce 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())
Anche qui non è necessario scrivere codice aggiuntivo — se nel task si verifica
un'eccezione, il metodo exception()
sarà chiamato dall'operatore await
.
Metodo Task.add_done_callback(callback)
:
Aggiunge un callback (callback)
, che sarà chiamato al completamento del task.
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())
Al task può essere aggiunta una funzione che sarà automaticamente chiamata quando il task termina l'esecuzione. Questo approccio permette di rendere il codice molto flessibile. Inoltre, si possono aggiungere più funzioni e si possono aggiungere a qualsiasi task.
Metodo Task.done()
:
Restituisce True
se il task è completato (con successo, con errore o è stato
cancellato).
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())
Con il metodo done()
puoi sapere se un task è stato eseguito con successo.
Più precisamente, se è terminato o è stato cancellato, perché se
è stata sollevata un'eccezione, formalmente il task potrebbe non essere completato,
ma non è stato nemmeno cancellato. Insomma, se il task è stato cancellato (cancel)
,
il metodo restituirà False
, altrimenti restituirà True
.
GO TO FULL VERSION