python - 我是否正在处理一个忽略 CancelledError 的异步任务?
问题描述
我不是在问如何取消这样的任务。这是不可能的,它在这里解释:https ://stackoverflow.com/a/33578893/5378816
我担心的是wait_for的这种变化:
在 3.7 版更改: 当 aw 由于超时而被取消时,wait_for 等待 aw 被取消。以前,它会立即引发 asyncio.TimeoutError。
不要误会我的意思,我喜欢它,这是一种改进。
但是,该程序现在将挂起wait_for
(Python 3.7):
import asyncio
async def uncancellable():
while True:
try:
await asyncio.sleep(99)
except asyncio.CancelledError:
print("sorry!")
TIMEOUT = 1.0
async def test():
task = asyncio.get_event_loop().create_task(uncancellable())
try:
await asyncio.wait_for(task, TIMEOUT)
except asyncio.TimeoutError:
print("timeout")
asyncio.get_event_loop().run_until_complete(test())
不可取消的任务是编程错误。但是如果我需要防御,我该如何防止wait_for
无限期挂起?
我试过这个。第一次超时:取消前,第二次超时:放弃前。
await asyncio.wait_for(asyncio.wait_for(task, TIMEOUT1), TIMEOUT1+TIMEOUT2)
有一个小问题我不太关心。当它出现时,asyncio.TimeoutError
我无法判断它是在第一次超时还是在第二次超时时发生的。基本上我认为它有效,但它真的正确吗?
解决方案
但是如果我需要防御,我如何防止 wait_for 无限期挂起?
我不认为将每项任务都视为可能无法取消是一个好主意。
通常你只是假设这种情况不会发生并且没关系,因为,是的,不可取消的任务是一个编程错误,它不是你期望经常看到的一种错误。同样的方式,您通常不会期望某些内部代码会抑制KeyboardInterrupt
或任何其他 BaseException
.
期望第三方代码遵循某些合同并没有错(例如上面的示例,或者说不是随机调用sys.exit()
)。否则,您将不得不编写更多代码,并且可能仍然无法涵盖所有可能的情况。
推荐阅读
- python - 我希望能够通过输入输入一个单词,如果该单词包含英语则返回 true,如果不包含则返回 false
- python - 如何访问 Numpy Polynomial.fit 的输出?
- powershell - 有没有办法根据文件资源管理器中的文件选择将击键输入到 Internet Explorer 中运行的 Web 应用程序中
- cefsharp - CefSharp IAudioHandler - 如何保存到可播放文件
- sql - 如何在 VSCODE 上调试 SQLite
- python - pygame 鼠标上的图像位置关闭如何解决?
- lc3 - 如何使此 LC-3 代码计算存储在 R0 中的值中 0 的数量并将结果存储到 R1
- html - 仅对第一个节点使用 ::before
- java - 如何检查过滤器是否有效?- 测试过滤器
- reactjs - useState() 导致音频对象出现意外行为