欢迎访问宙启技术站
智能推送

Python中的CancelledError()异常对协程和异步任务的影响与处理方法

发布时间:2023-12-24 12:36:35

Python中的CancelledError异常是一个特殊的异常,它在协程或异步任务被取消时引发。当我们使用asyncio库进行协程和异步编程时,我们可以通过调用协程或异步任务的cancel()方法来取消它们。取消操作会导致协程或异步任务引发CancelledError异常。这个异常通常用于控制协程或异步任务的执行流程,以便在取消时执行特定的操作。

为了更好地理解CancelledError异常,让我们来看一个简单的示例。假设我们有一个协程函数fetch_data(),用于模拟从网络中获取数据的操作。我们可以使用asyncio库将这个函数转换成一个协程对象,并使用asyncio.run()函数来运行它。

import asyncio

async def fetch_data(url):
    print(f"Fetching data from {url}")
    await asyncio.sleep(2)  # 模拟网络请求延迟
    print(f"Data fetched from {url}")

async def main():
    task = asyncio.create_task(fetch_data("https://example.com"))
    await asyncio.sleep(1)
    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("Task cancelled")

asyncio.run(main())

在上面的例子中,我们定义了一个名为fetch_data()的协程函数,用于从指定的URL获取数据。我们使用asyncio.sleep()函数模拟了一个2秒的网络请求延迟。然后,我们定义了一个名为main()的协程函数,该函数首先创建了一个任务对象(task),并将fetch_data()协程作为任务的执行体。然后,我们使用asyncio.sleep()函数暂停了1秒钟,模拟了在发送请求后给予请求一些时间以获取数据的情况。随后,我们调用了task.cancel()方法来取消异步任务。最后,我们在try-except代码块中通过捕获CancelledError异常来处理任务被取消时的情况。

运行上述代码,可以看到以下输出:

Fetching data from https://example.com
Task cancelled

从输出中可以看出,当我们调用cancel()方法来取消任务时(在此例中为fetch_data协程),任务中的代码会立即引发CancelledError异常。接着我们通过捕获CancelledError异常来处理任务被取消时的情况,并打印出"Task cancelled"。

处理CancelledError异常的常见方法之一是在协程中使用try-except代码块。然而,有时我们可能需要继续执行一些清理操作或执行其他特定操作来处理任务取消的情况。这可以通过添加相应的代码来实现。

import asyncio

async def fetch_data(url):
    try:
        while True:
            print(f"Fetching data from {url}")
            await asyncio.sleep(1)
    except asyncio.CancelledError:
        print(f"Cancelled fetch_data for {url}")
        # 执行一些清理操作或其他处理

async def main():
    task = asyncio.create_task(fetch_data("https://example.com"))
    await asyncio.sleep(5)
    task.cancel()
    #执行其他清理或处理操作

asyncio.run(main())

在上述代码中,我们对fetch_data()协程函数进行了一些修改,使其在被取消时重复打印"Cancelled fetch_data for {url}"。这样我们可以执行一些清理操作或其他特定操作。在main()函数中,我们添加了一些其他的清理或处理操作。

运行上述代码,可以看到以下输出:

Fetching data from https://example.com
Fetching data from https://example.com
Fetching data from https://example.com
Fetching data from https://example.com
Cancelled fetch_data for https://example.com

从输出中可以看出,当我们调用cancel()方法来取消任务时,任务中的代码会立即引发CancelledError异常。接着我们通过捕获CancelledError异常来处理任务被取消时的情况,并打印出"Cancelled fetch_data for {url}"。同时我们也可以在except代码块中执行其他特定的清理或处理操作。

总结来说,CancelledError异常在协程或异步任务被取消时会被引发。我们可以通过捕获CancelledError异常来处理任务取消的情况,并在处理代码块中执行一些清理操作或其他特定操作,以满足我们的需求。