python - Asyncio - 检查事件循环中是否具有特定参数的协程的方法?

标签 python python-asyncio

在我的应用程序中,我有多个类,这些类可能会导致向 event_loop 添加协程。但我不希望多次添加协程,因此我需要一种方法来检查协程是否已经是运行循环中的任务。

我找到了asyncio.Task.all_tasks(loop)类方法。我认为这可以解决我的问题,但输出仅给出协程名称,而不给出参数。这对我来说是一个问题,因为我向 event_loop 添加了具有不同参数集的相同协程。

演示:

import asyncio
from threading import Thread
from time import sleep

async def foo(a, b):
    while True:
        print("{}{}".format(a, b))
        await asyncio.sleep(1)

def loop_starter():
    loop1.create_task(foo("one","two"))
    loop1.create_task(foo("three","four"))
    loop1.run_forever()

loop1 = asyncio.new_event_loop()
t = Thread(target=loop_starter)
t.start()
sleep(0.5)
print(asyncio.Task.all_tasks(loop1))

all_tasks() 方法的输出是:

{<Task pending coro=<foo() running at example.py:8> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7f7dbb312b58>()]>>, 
 <Task pending coro=<foo() running at example.py:8> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7f7dbb2a4918>()]>>}

所以看来我无法知道 foo 的哪些版本已经在事件循环中。

最佳答案

我唯一想到的是这样的:

import asyncio


_running = list()  # set would be better if you have hashable values


def create_unique_task(coro_func, *args, **kwargs):
    loop = asyncio.get_event_loop()

    uid = (args, kwargs)
    if uid not in _running:
        task = loop.create_task(foo(*args, **kwargs))
        _running.append(uid)
        task.add_done_callback(lambda _: _running.remove(uid))
    else:
        print('skipped')
        return

    return task


async def foo(a, b):
    print("{} {}".format(a, b))
    await asyncio.sleep(0.5)


async def main():
    create_unique_task(foo, "one", "two")
    create_unique_task(foo, "three", "four")
    await asyncio.sleep(0.2)

    create_unique_task(foo, "one", "two")
    create_unique_task(foo, "three", "four")
    await asyncio.sleep(0.4)

    create_unique_task(foo, "one", "two")
    create_unique_task(foo, "three", "four")
    await asyncio.sleep(1)


if __name__ ==  '__main__':
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()

输出:

one two
three four
skipped
skipped
one two
three four

关于python - Asyncio - 检查事件循环中是否具有特定参数的协程的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49022546/

相关文章:

python - 在 Python 中模拟异步属性

python - 异步 : Is it possible to cancel a future been run by an Executor?

python - Python3.7 中的触发、遗忘和返回值

python - celery - 如何从远程机器发送任务?

python - pandas 与 numpy 的不同标准

python - Python 中 Json 覆盖自身

python - 在父对象销毁时关闭 aiohttp.ClientSession

python - 在 SqlAlchemy 中使用模型类类型的数组创建列

python - 将df中的许多列减去另一df中的一列

iterator - Python 3.6 : async version of islice?