【发布时间】:2019-12-30 19:41:56
【问题描述】:
我正在编写运行异步任务的 python 上下文管理器。如果任何任务引发异常,我希望我的经理终止。这是示例代码:
class MyClass:
def __init__(self):
if asyncio.get_event_loop().is_closed():
asyncio.set_event_loop(asyncio.new_event_loop())
self.loop = asyncio.get_event_loop()
def __enter__(self):
return self
def __exit__(self, excType, excValue, tb):
try:
self.loop.run_until_complete(self._exit_loop())
finally:
self.loop.close()
if excType is not None:
print(excType.__name__, ':', excValue)
traceback.print_tb(tb)
async def _exit_loop(self):
tasks = [task for task in asyncio.all_tasks(self.loop) if
task is not asyncio.current_task(self.loop)]
list(map(lambda task: task.cancel(), tasks))
results = await asyncio.gather(*tasks, return_exceptions=True)
self.loop.stop()
async def func1(self):
while True:
print('func1')
await asyncio.sleep(1)
async def func2(self):
i = 5
while i > 0:
print('func2')
await asyncio.sleep(1)
i -= 1
raise Exception
async def _async_start(self):
self.loop.create_task(self.func1())
self.loop.create_task(self.func2())
def start(self):
self.loop.run_until_complete(self._async_start())
with MyClass() as myClass:
myClass.start()
myClass.loop.run_forever()
这是此脚本的输出:
func1
func2
func1
func2
func1
func2
func1
func2
func1
func2
Task exception was never retrieved
func1
future: <Task finished coro=<MyClass.func2() done, defined at /home/framal/Programy/schnapps/schnapps/bottle/client.py:381> exception=Exception()>
Traceback (most recent call last):
File "/home/framal/Programy/schnapps/schnapps/bottle/client.py", line 387, in func2
raise Exception
Exception
func1
func1
func1
.
.
.
我尝试使用自定义异常处理程序,但没有任何效果 - 它们在强制终止进程后开始运行。
如何将异常传递给循环,以便它关闭所有其他任务?
【问题讨论】:
-
你确定要在那里打电话给
run_forever()吗?它就像名字所说的那样,永远运行循环,这就是你的__exit__永远不会被调用的原因。顺便说一句,您是否尝试过从自定义异常处理程序调用self.loop.stop()? -
@user4815162342 我这样做只是为了举例,我不希望程序在启动后立即终止
标签: python asynchronous exception python-asyncio with-statement