简体   繁体   English

如何在 asyncio 引发 TimeoutError 之前由 asyncio 任务本身处理超时异常

[英]How to handle Timeout Exception by the asyncio task itself just before asyncio raise TimeoutError

Due to one use case, One of my long-running functions executes multiple instructions.由于一个用例,我的一个长时间运行的函数执行了多条指令。 But I have to give a maximum time for its execution.但我必须为其执行提供最长时间。 If the function is not able to finish its execution within the allocated time, it should clean up the progress and return.如果function不能在分配的时间内完成执行,它应该清理进度并返回。

Let's have a look at a sample code below:让我们看一下下面的示例代码:

import asyncio

async def eternity():
    # Sleep for one hour
    try:
        await asyncio.sleep(3600)
        print('yay!, everything is done..')
    except Exception as e:
        print("I have to clean up lot of thing in case of Exception or not able to finish by the allocated time")


async def main():
    try:
        ref = await asyncio.wait_for(eternity(), timeout=5)
    except asyncio.exceptions.TimeoutError:
        print('timeout!')

asyncio.run(main())

The function eternity is the long-running function. The catch is that, in case of some exception or reaching the maximum allocated time, the function needs to clean up the mess it has made. function eternity是长期运行的 function。要注意的是,如果出现某些异常或达到最大分配时间,function 需要清理它造成的混乱。

PS eternity is an independent function and only it can understand what to clean. PS eternity是一个独立的 function 只有它能理解要清理什么。

I am looking for a way to raise an exception inside my task just before the timeout, OR send some interrupt or terminate signal to the task and handle it.我正在寻找一种方法在超时之前在我的任务中引发异常,或者向任务发送一些中断或终止信号并处理它。
Basically, I want to execute some peice of code in my task before asyncio raises the TimeoutError and take control.基本上,我想在 asyncio 引发TimeoutError并取得控制权之前在我的任务中执行一些代码。
Also, I am using Python 3.9.另外,我正在使用 Python 3.9。
Hope I was able to explain the problem.希望我能够解释这个问题。

What you need is async context manager:您需要的是异步上下文管理器:

import asyncio

class MyClass(object):

    async def eternity(self):
        # Sleep for one hour
        await asyncio.sleep(3600)
        print('yay!, everything is done..')

    async def __aenter__(self):
        return self

    async def __aexit__(self, exc_type, exc, tb):
        print("I have to clean up lot of thing in case of Exception or not able to finish by the allocated time")


async def main():
    try:
        async with MyClass() as my_class:
            ref = await asyncio.wait_for(my_class.eternity(), timeout=5)
    except asyncio.exceptions.TimeoutError:
        print('timeout!')


asyncio.run(main())

And this is the output:这是 output:

I have to clean up lot of thing in case of Exception or not able to finish by the allocated time
timeout!

For more details take a look at here .有关详细信息,请查看此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM