Cancelando Tarefas

Resumo : neste tutorial, você aprenderá como cancelar uma operação assíncrona de longa duração que pode levar uma eternidade para ser concluída.

A instrução a seguir usa a awaitinstrução para aguardar a conclusão de uma tarefa :

task = asyncio.create_task(coroutine())

result = await taskLinguagem de código:  Python  ( python )

Porém, se coroutine()demorasse uma eternidade, você ficaria esperando o awaittérmino da instrução sem obter nenhum resultado. Além disso, você não teria como pará-lo se quisesse.

Para resolver isso, você pode cancelar a tarefa usando o cancel()método do Taskobjeto. Se você cancelar uma tarefa, isso gerará uma CancelledErrorexceção quando você fizer awaitisso. Por exemplo:

import asyncio
from asyncio import CancelledError


async def call_api(message, result=1000, delay=3):
    print(message)
    await asyncio.sleep(delay)
    return result


async def main():
    task = asyncio.create_task(
        call_api('Calling API...', result=2000, delay=5)
    )

    if not task.done():
        print('Cancelling the task...')
        task.cancel()

    try:
        await task
    except CancelledError:
        print('Task has been cancelled.')


asyncio.run(main())Linguagem de código:  Python  ( python )

Saída:

Cancelling the task...
Task has been cancelledLinguagem de código:  Python  ( python )

Como funciona.

Primeiro, a call_api()corrotina imprime uma mensagem, atrasa 3 segundos e retorna o resultado.

Segundo, crie uma nova tarefa usando a create_task()função e passe a call_api()corrotina. A tarefa levará 5 segundos para ser concluída:

task = asyncio.create_task(
    call_api('Calling API...', result=2000, delay=5)
)Linguagem de código:  Python  ( python )

Terceiro, verifique se a tarefa não foi concluída chamando o done()método e cancele a tarefa usando o cancel()método:

if not task.done():
    print('Cancelling the task...')
    task.cancel()Linguagem de código:  Python  ( python )

Por fim, aguarde a conclusão da tarefa usando a awaitpalavra-chave. Como a tarefa foi cancelada, a CancelledErrorexceção é levantada:

try:
    await task
except CancelledError:
    print('Task has been cancelled.')Linguagem de código:  Python  ( python )

Se você quiser verificar a cada segundo se uma tarefa foi concluída e cancelá-la se tiver passado algum tempo, você pode usar um whileloop:

import asyncio
from asyncio import CancelledError


async def call_api(message, result=1000, delay=3):
    print(message)
    await asyncio.sleep(delay)
    return result


async def main():
    task = asyncio.create_task(
        call_api('Calling API...', result=2000, delay=5)
    )

    time_elapsed = 0
    while not task.done():
        time_elapsed += 1
        await asyncio.sleep(1)
        print('Task has not completed, checking again in a second')
        if time_elapsed == 3:
            print('Cancelling the task...')
            task.cancel()
            break

    try:
        await task
    except CancelledError:
        print('Task has been cancelled.')


asyncio.run(main())Linguagem de código:  Python  ( python )

Neste exemplo, o whileloop verifica se a tarefa foi concluída a cada segundo e cancela a tarefa quando o tempo decorrido atinge 3 segundos.

Resumo

  • Use o cancel()método do Taskobjeto para cancelar uma tarefa
  • aguardar uma tarefa cancelada gerará uma CancelledErrorexceção.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *