Classe Task

Python SELF IT
Livello 26 , Lezione 0
Disponibile

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.

  1. Creiamo un task asincrono che aspetterà per 10 secondi
  2. Lo avvolgiamo in un oggetto Task
  3. Aspettiamo un secondo affinché il task inizi l'esecuzione
  4. Cancelliamo il task – task.cancel()
  5. Se poi tentiamo di attendere il completamento del task usando l'operatore await, otterremo un'eccezione CancelledError.

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.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION