Canceling Tasks

Created with Sketch.

Canceling Tasks

Summary: in this tutorial, you’ll learn how to cancel a long-running asynchronous operation that may take forever to complete.

The following statement uses the await statement to wait for a task to be complete:

task = asyncio.create_task(coroutine())

result = await task

Code language: Python (python)

However, if the coroutine() took forever, you would be stuck waiting for the await statement to finish with no result. Also, you had no way to stop it if you wanted to.

To resolve this, you can cancel the task using the cancel() method of the Task object. If you cancel a task, it’ll raise the CancelledError exception when you await it. For example:

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())

Code language: Python (python)

Output:

Cancelling the task...
Task has been cancelled

Code language: Python (python)

How it works.

First, the call_api() coroutine prints a message, delays 3 seconds, and returns the result.

Second, create a new task using the create_task() function and pass the call_api() coroutine. The task will take 5 seconds to complete:

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

Code language: Python (python)

Third, check if the task is not done by calling the done() method and cancel the task using the cancel() method:

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

Code language: Python (python)

Finally, wait for the task to be completed using the await keyword. Since the task has been canceled, the CancelledError exception is raised:

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

Code language: Python (python)

If you want to check every second if a task has been completed and cancel it if an amount of time has passed, you can use a 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())

Code language: Python (python)

In this example, the while loop checks if the task has been completed every second and cancels the task once the elapsed time reaches 3 seconds.

Summary

  • Use the cancel() method of the Task object to cancel a task
  • await a cancelled task will raise a CancelledError exception.

Leave a Reply

Your email address will not be published. Required fields are marked *