当使用asyncio.wait_for和asyncio.Semaphore时,如何正确的捕捉concurrent.futures._base.TimeoutError?

问题描述 投票:0回答:1

首先,我需要警告你,我是新来的asyncio,而且我很讨厌使用asyncio.wait_for和asyncio.Semaphore。我是新来的asyncio, 我马上警告你, 我是新来的asyncio, 我很难想象库里的东西是什么.

这是我的代码。

import asyncio

semaphore = asyncio.Semaphore(50)

async def work(value):
    async with semaphore:
        print(value)
        await asyncio.sleep(10)

async def main():
    tasks = []
    for i in range(0, 10000):
        tasks.append(asyncio.wait_for(work(i), timeout=3))
    await asyncio.gather(*tasks)

loop = asyncio.get_event_loop()
future = asyncio.ensure_future(main())
loop.run_until_complete(future)

我需要的是: Coroutine work()完成的时间不超过3秒 同时完成的数量不超过50件。3秒后(超时),coroutine work()必须停止执行,新的50个任务必须开始工作。但在我的情况下,3秒后就崩溃了。

Traceback (most recent call last):
  File "C:/Users/root/PycharmProjects/LogParser/ssh/async/asyn_test.py", line 19, in <module>
    loop.run_until_complete(future)
  File "C:\Code\Python3\lib\asyncio\base_events.py", line 579, in run_until_complete
    return future.result()
  File "C:/Users/root/PycharmProjects/LogParser/ssh/async/asyn_test.py", line 15, in main
    await asyncio.gather(*tasks)
  File "C:\Code\Python3\lib\asyncio\tasks.py", line 449, in wait_for
    raise futures.TimeoutError()
concurrent.futures._base.TimeoutError

不管我有没有尝试抓住这个异常,不管还有多少任务,程序都会崩溃。我需要,达到超时后,程序继续到下一个任务,请教我,我需要如何正确地实现这一点?

Python 3.7,asyncio 3.4.3。

python python-3.x async-await python-asyncio semaphore
1个回答
0
投票

你需要处理异常。如果你只是把它传给 gather,它将重新提起它。例如,你可以用适当的tryexcept创建一个新的coroutine。

semaphore = asyncio.Semaphore(50)

async def work(value):
    print(value)
    await asyncio.sleep(10)

async def work_with_timeout(value):
    async with semaphore:
        try:
            return await asyncio.wait_for(work(value), timeout=3)
        except asyncio.TimeoutError:
            return None

async def main():
    tasks = []
    for i in range(0, 10000):
        tasks.append(work_with_timeout(i))
    await asyncio.gather(*tasks)
© www.soinside.com 2019 - 2024. All rights reserved.