异步异常处理程序:在事件循环线程停止之前不会被调用

2024-05-14

我正在我的异步事件循环上设置异常处理程序。但是,在事件循环线程停止之前,它似乎不会被调用。例如,考虑以下代码:

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))它不再打印任何东西。

我对此有几个问题:

  • 我在这里做错了什么吗?

  • 有谁知道这是否是 asyncio 异常处理程序的预期行为?我找不到任何记录这一点的内容,这对我来说似乎有点奇怪。

我非常希望有一个长时间运行的事件循环来记录其协程中发生的错误,因此当前的行为对我来说似乎有问题。


上面的代码有几个问题:

  • 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()返回一个保存异常的 future 对象(它不会到达默认的异常处理程序):

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() or ensure_future()将调用异常处理程序:

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 https://docs.python.org/3/library/queue.html与您的线程进行通信。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

异步异常处理程序:在事件循环线程停止之前不会被调用 的相关文章

随机推荐

  • 可选回调的 JavaScript 样式

    我有一些函数偶尔 并非总是 会收到回调并运行它 检查回调是否已定义 函数是一种好的风格还是有更好的方法 Example function save callback do stuff if typeof callback undefined
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • SimpleMembershipProvider 在 WebSecurity.SignOut 之后不会销毁会话

    我正在使用所有默认成员代码运行 ASP NET MVC 4 AccountController的LogOff的代码是 HttpPost ValidateAntiForgeryToken public ActionResult LogOff
  • 给定的 System.Uri 无法转换为 Windows.Foundation.Uri

    我正在尝试以编程方式在 XAML Metro 应用程序中加载 BitmapImage 这是我的代码 var uri new Uri Images 800x600 BackgroundTile bmp UriKind RelativeOrAb
  • 如何在 Oracle 上生成版本 4(随机)UUID?

    该博客解释说 输出sys guid 对于每个系统来说不是随机的 http feuerthoughts blogspot de 2006 02 watch out for sequential oracle guids html http f
  • 无法将matplotlib安装到pycharm

    我最近开始使用Python速成课程学习Python编程 我陷入困境 因为我无法让 matplotlib 在 pycharm 中工作 我已经安装了pip 我已经通过命令提示符使用 pip 安装了 matplotlib 现在 当我打开 pych
  • 如何使用 jest 通过 Promise.all 设置多次提取测试

    我在测试中使用 jest 我正在使用 React 和 Redux 并且执行以下操作 function getData id notify return dispatch gt dispatch anotherFunction Promise
  • 我应该在 PHP 代码中使用断言吗?

    一位同事添加了assert http php net assert在我们的库中 在我本来会使用 if 语句并引发异常的地方执行几次命令 在此之前我什至从未听说过断言 以下是他如何使用它的示例 assert isset this gt rec
  • Rails 4 - 如何链接到 PDF 文件(名称.PDF)?

    我正在生成 PDF 文件 我的链接如下所示 当我点击这个时 它会带我去 display invoice 123456789 这是一个 HTML 版本 在控制器中的操作如下 def display invoice if params invo
  • 文本视图不显示全文

    我正在使用 TableLayout 和 TableRow 创建一个简单的布局 其中包含两个 TextView 这是代码的一部分
  • 如何更改元素的 CSS 类并在单击时删除所有其他类

    我如何处理 AngularJS 2 中的一种情况 即单击一个元素需要更改其自己的样式 并且如果其他元素具有该样式 则需要将其删除 最好在一个函数中 如同Angular js 如何在单击时更改元素 css 类并删除所有其他元素 https s
  • 如何在html中设置按钮的文本大小

    您好 我想在我的网站上有一个按钮 并且我想调整按钮上的文本大小 我该怎么做呢 我的代码如下
  • 增加内存限制时出现奇怪的错误

    我使用的是共享托管环境 PHP 的默认内存限制是 32M 我在 Concrete5 设置方面遇到一些问题 当我尝试登录 Concrete5 的管理面板时 出现内存限制错误Allowed memory size of 33554432 byt
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • 在 Spring Security ACL 中授予权限

    我在 grails 1 3 7 中使用 Spring Security ACL 插件 但我的问题可能比这更通用 我想允许拥有以下权限的用户BasePermission READ访问对象以便能够向其他用户授予相同的权限 如果 user1 具有
  • 如何在 C++ 中将 CString 转换为 double?

    我如何转换CString to a double在 C 中 Unicode 支持也很好 Thanks A CString可以转换为LPCTSTR 这基本上是一个const char const wchar t 在 Unicode 版本中 知
  • Rails 中的 PDF 导出

    我需要将包含一些图表的 HTML 页面导出为 PDF 有哪些好的 gem 可以做到这一点 PDFKit http railscasts com episodes 220 pdfkit http railscasts com episodes
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • 更改用作函数全局作用域的字典

    我想做一个 purePython 的装饰器 其中一部分是能够有选择地禁止访问函数的全局范围 有没有一种方法可以以编程方式更改哪个字典事物充当函数的全局 外部作用域 因此 例如在下面我希望能够拦截对f in h并抛出错误 但我想允许访问g因为
  • 异步异常处理程序:在事件循环线程停止之前不会被调用

    我正在我的异步事件循环上设置异常处理程序 但是 在事件循环线程停止之前 它似乎不会被调用 例如 考虑以下代码 def exception handler loop context print Exception handler called