Asyncio exception handler: not getting called until event loop thread stopped(异步异常处理程序:在事件循环线程停止之前不会调用)
                            本文介绍了异步异常处理程序:在事件循环线程停止之前不会调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
                        
                        问题描述
我正在异步事件循环上设置异常处理程序。但是,在事件循环线程停止之前,似乎不会调用它。例如,请考虑以下代码:
def exception_handler(loop, context):
    print('Exception handler called')
loop = asyncio.get_event_loop()
loop.set_exception_handler(exception_handler)
thread = Thread(target=loop.run_forever)
thread.start()
async def run():
    raise RuntimeError()
asyncio.run_coroutine_threadsafe(run(), loop)
loop.call_soon_threadsafe(loop.stop, loop)
thread.join()
如我们所料,此代码打印"调用的异常处理程序"。但是,如果我删除关闭事件循环的行(loop.call_soon_threadsafe(loop.stop, loop)),它将不再打印任何内容。
我对此有几个问题:
我是否做错了什么?
有人知道这是否是异步异常处理程序的预期行为?我找不到任何记录这件事的东西,这对我来说似乎有点奇怪。
我非常希望有一个长期运行的事件循环来记录协同例程中发生的错误,因此当前的行为对我来说似乎有问题。
推荐答案
上面的代码有几个问题:
stop()不需要参数- 程序在执行协程之前结束(
stop()在它之前被调用)。 
以下是已修复的代码(没有异常和异常处理程序):
import asyncio
from threading import Thread
async def coro():
    print("in coro")
    return 42
loop = asyncio.get_event_loop()
thread = Thread(target=loop.run_forever)
thread.start()
fut = asyncio.run_coroutine_threadsafe(coro(), loop)
print(fut.result())
loop.call_soon_threadsafe(loop.stop)
thread.join()
call_soon_threadsafe()返回保存异常的未来对象(它不会到达默认的异常处理程序):
import asyncio
from pprint import pprint
from threading import Thread
def exception_handler(loop, context):
    print('Exception handler called')
    pprint(context)
loop = asyncio.get_event_loop()
loop.set_exception_handler(exception_handler)
thread = Thread(target=loop.run_forever)
thread.start()
async def coro():
    print("coro")
    raise RuntimeError("BOOM!")
fut = asyncio.run_coroutine_threadsafe(coro(), loop)
try:
    print("success:", fut.result())
except:
    print("exception:", fut.exception())
loop.call_soon_threadsafe(loop.stop)
thread.join()
但是,使用create_task()或ensure_future()调用的协同例程将调用EXCEPTION_HANDLER:
async def coro2():
    print("coro2")
    raise RuntimeError("BOOM2!")
async def coro():
    loop.create_task(coro2())
    print("coro")
    raise RuntimeError("BOOM!")
您可以使用它创建一个小包装:
async def boom(x):
    print("boom", x)
    raise RuntimeError("BOOM!")
async def call_later(coro, *args, **kwargs):
    loop.create_task(coro(*args, **kwargs))
    return "ok"
fut = asyncio.run_coroutine_threadsafe(call_later(boom, 7), loop)
但是,您可能应该考虑改用Queue与您的线程通信。
这篇关于异步异常处理程序:在事件循环线程停止之前不会调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
				 沃梦达教程
				
			本文标题为:异步异常处理程序:在事件循环线程停止之前不会调用
				
        
 
            
        
             猜你喜欢
        
	     - 分析异常:路径不存在:dbfs:/databricks/python/lib/python3.7/site-packages/sampleFolder/data; 2022-01-01
 - padding='same' 转换为 PyTorch padding=# 2022-01-01
 - pytorch 中的自适应池是如何工作的? 2022-07-12
 - 沿轴计算直方图 2022-01-01
 - 如何将一个类的函数分成多个文件? 2022-01-01
 - 如何在 python3 中将 OrderedDict 转换为常规字典 2022-01-01
 - 如何在 Python 的元组列表中对每个元组中的第一个值求和? 2022-01-01
 - python check_output 失败,退出状态为 1,但 Popen 适用于相同的命令 2022-01-01
 - python-m http.server 443--使用SSL? 2022-01-01
 - 使用Heroku上托管的Selenium登录Instagram时,找不到元素';用户名'; 2022-01-01
 
				
				
				
				