Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将自定义异常抛出到正在运行的任务中_Python_Python 3.x_Python Asyncio - Fatal编程技术网

Python 如何将自定义异常抛出到正在运行的任务中

Python 如何将自定义异常抛出到正在运行的任务中,python,python-3.x,python-asyncio,Python,Python 3.x,Python Asyncio,我试图弄清楚是否有可能将自定义异常抛出到正在运行的异步IO任务中,类似于task.cancel(self)所实现的,它计划在底层协同程序中引发canceledError 我遇到了Task.get_coro().throw(exc),但调用它似乎是打开了一个大的蠕虫罐头,因为我们可能会让任务处于一种糟糕的状态。特别是考虑到所有的机器发生时,一个 考虑以下示例: 导入异步IO 类重置(异常): 通过 异步定义无限() 尽管如此: 尝试: 打印(‘工作’) 等待asyncio.sleep(1) 打印(

我试图弄清楚是否有可能将自定义异常抛出到正在运行的异步IO任务中,类似于
task.cancel(self)
所实现的,它计划在底层协同程序中引发
canceledError

我遇到了
Task.get_coro().throw(exc)
,但调用它似乎是打开了一个大的蠕虫罐头,因为我们可能会让任务处于一种糟糕的状态。特别是考虑到所有的机器发生时,一个

考虑以下示例:

导入异步IO
类重置(异常):
通过
异步定义无限()
尽管如此:
尝试:
打印(‘工作’)
等待asyncio.sleep(1)
打印(“更多工作”)
除重置外:
打印('重置')
持续
除asyncio.Cancelled错误外:
打印('取消')
打破
异步def main():
无限任务=异步。创建任务(无限()
等待asyncio.sleep(0)#允许无限_任务进入其工作循环。
无限任务。获取\u coro()。抛出(重置())
等待无限的任务
asyncio.run(main())
##输出##
#“工作”
#“重置”
#“工作”
#永远挂着。。。坏的:(

我试图做的事情是否可行?感觉好像我不应该像这样操纵底层的协同程序。有什么解决方法吗?

没有办法将自定义异常抛出到正在运行的任务中。你不应该弄乱
。抛出
-这是实现的一个细节,修改它可能会破坏一些东西

如果要将信息(关于重置)传递到任务中,请通过参数进行传递。以下是实现方法:

import asyncio
from contextlib import suppress


async def infinite(need_reset):
    try:
        while True:
            inner_task = asyncio.create_task(inner_job())

            await asyncio.wait(
                [
                    need_reset.wait(),
                    inner_task
                ], 
                return_when=asyncio.FIRST_COMPLETED
            )

            if need_reset.is_set():
                print('reset')
                await cancel(inner_task)
                need_reset.clear()
    except asyncio.CancelledError:
        print('cancel')
        raise  # you should never suppress, see:
               # https://stackoverflow.com/a/33578893/1113207


async def inner_job():
    print('work')
    await asyncio.sleep(1)
    print('more work')


async def cancel(task):
    # more info: https://stackoverflow.com/a/43810272/1113207
    task.cancel()
    with suppress(asyncio.CancelledError):
        await task


async def main():
    need_reset = asyncio.Event()
    infinite_task = asyncio.create_task(infinite(need_reset))

    await asyncio.sleep(1.5)
    need_reset.set()

    await asyncio.sleep(1.5)
    await cancel(infinite_task)


asyncio.run(main())
输出:

work
more work
work
reset
work
more work
work
cancel