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 await
instrução para aguardar a conclusão de uma tarefa :
task = asyncio.create_task(coroutine())
result = await task
Linguagem de código: Python ( python )
Porém, se coroutine()
demorasse uma eternidade, você ficaria esperando o await
té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 Task
objeto. Se você cancelar uma tarefa, isso gerará uma CancelledError
exceção quando você fizer await
isso. 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 cancelled
Linguagem 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 await
palavra-chave. Como a tarefa foi cancelada, a CancelledError
exceçã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 while
loop:
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 while
loop 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 doTask
objeto para cancelar uma tarefa - aguardar uma tarefa cancelada gerará uma
CancelledError
exceção.