python - 是否可以屏蔽后台任务被 asyncio.run() 取消?
问题描述
假设我有一个应用程序处理队列中的一些任务。我希望能够中断/终止循环,但首先要完成任何消息的处理。
async def run():
while True:
msg = await queue.get()
await asyncio.shield(process_msg(msg))
# Or, maybe asyncio.create_task()
asyncio.run(run())
使用这样的代码,主任务将被中断并取消,但随后asyncio.run()
会尝试取消所有剩余的任务,从而导致process_msg()
任务被取消。
那么,有没有什么通用的方法可以防止任务在关机时被取消?这似乎是一种足够常见的设计模式,我希望它已经被考虑过,但我没有在网上找到任何东西。
使用低级 API,我目前想出了类似的东西来替换asyncio.run()
:
loop = asyncio.get_event_loop()
t = loop.create_task(run())
for s in (SIGINT, SIGTERM):
loop.add_signal_handler(s, t.cancel)
with suppress(asyncio.CancelledError):
loop.run_until_complete(t)
loop.run_until_complete(asyncio.gather(*asyncio.all_tasks(loop)))
对于这个简单的示例,这可能很好,但对于更复杂的应用程序,可能需要由处理取消asyncio.run()
并有一种方法来保护特定任务免受关闭取消。
普遍的共识是asyncio.run()
几乎所有时间都应该使用它,我们不应该为典型的应用程序需要低级 API,但这对我来说似乎是一个相当常见的应用程序设计。那么,我是否遗漏了一些可以适应这种方法的东西?
解决方案
推荐阅读
- google-apps-script - How to make Card Header Title bold in Gmail Add-on?
- awk - How to inlcude functions from another file in a awk script using nextflow
- python - 如何确保请求是从 Rotating IPs 发出的?
- python - 如何在 PyQt5 的 QTableview 中将列压缩到最小?
- android - 在android上插入房间数据后第二次查询后获取数据
- typescript - 如何在打字稿中访问对象对象 - Ionic 3
- node.js - 安装 CLI 后我无法安装 Angular 应用程序
- web-config - 在 IIS10 中将带有哈希码的 URL 重定向到另一个具有相同哈希码的 URL
- xamarin.android - How to cancel IMvxAsyncCommand?
- c - C中的“表达式必须具有整数类型”开关问题