[英]Asyncio - way to check if coroutine with specific arguments in event loop?
In my app I have multiple classes which could have cause to add a coroutine to an event_loop.在我的应用程序中,我有多个类可能会导致向 event_loop 添加协程。 But I don't want a coroutine to be added more than once, so I need a way to check if the coroutine is already a task in the running loop.
但是我不希望一个协程被添加不止一次,所以我需要一种方法来检查协程是否已经是运行循环中的一个任务。
I have found the asyncio.Task.all_tasks(loop) class method.我找到了asyncio.Task.all_tasks(loop)类方法。 I thought this would solve my problem but the output gives only the coroutine names and not the arguments.
我认为这会解决我的问题,但输出只给出了协程名称而不是参数。 This is a problem for me because I am adding the same coroutine with varying sets of arguments to the event_loop.
这对我来说是个问题,因为我正在向 event_loop 添加具有不同参数集的相同协程。
To demonstrate:展示:
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))
The output of the all_tasks() method is: 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>()]>>}
So it appears I have no way of knowing which versions of foo are in the event loop already.所以看起来我无法知道哪些版本的 foo 已经在事件循环中了。
Only thing that comes to mind is something like this:唯一想到的是这样的:
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()
Output:输出:
one two
three four
skipped
skipped
one two
three four
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.