首页 > 解决方案 > 避免使用相同的变量命名不同的异步任务,以防止无法停止的任务

问题描述

我正在尝试创建一个实时编码环境,编码人员可以在其中创建和停止异步任务。

我启动了一个交互式python会话/ asyncio REPL

python -m asyncio.

然后我允许用户按名称创建异步任务,如下所示:

import asyncio # executed with 'python -m asyncio' command

# simple async function
async def sleep(sleep_time):
    while True:
        print(f'sleeping for {sleep_time} seconds.')
        await asyncio.sleep(sleep_time)

x = asyncio.create_task(sleep(2))
y = asyncio.create_task(sleep(4))

这将创建两个异步运行的任务 x 和 y。

这些任务可以很容易地停止

x.cancel()y.cancel()

x = asyncio.create_task(sleep(3))但是如果用户在执行之前执行了一个同名的新任务x.cancel(),两个“x”任务将同时运行。 x.cancel()将停止x(sleeping for 3 seconds) 的最后定义,但 x-sleeping for 2 seconds-的原始定义仍将运行。没有简单的方法可以停止x仍在后台运行的此任务。 x.cancel()返回False而不是True.

如果用户不小心两次使用相同的变量名,我的目标是避免在后台运行不可阻挡的任务。有没有办法阻止用户为x变量分配新定义?还是完全更好的策略?

可以接受特定于 asyncio 的或基本的 Python 解决方案。

谢谢你。

标签: pythonipythonpython-asyncio

解决方案


if "x" in globals():
    x.cancel()
    del x

像这样的东西可能有用吗?if "x" in globals():检查 x 是否已定义,del x"undefines" x

或者也许使用:在未定义的情况下try执行取消并捕获NameError异常x

try:
    x.cancel()
except NameError:
    ...

如果您只想这样做prevent the user from launching a new task with the same name as an existing task,可能仍会使用相同的技术,也许是这样的:

if "x" in globals():
    if not x.done():
       print(" Another task with the same name is running... ")
    else:
       x = asyncio.create_task(sleep(3))
else:
    x = asyncio.create_task(sleep(3))


推荐阅读