谁能说出下面的代码为什么
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1
在下面得到错误:
import asyncio
import time
from concurrent.futures import ThreadPoolExecutor
ASYNC_INTERVAL = 0.1
def plain_hello_world(name):
s = "Hello world "+str(name)
print(s)
return s
def plain_loop(name, t):
start_time = time.time()
prev_time = start_time
while (time.time() - start_time < t):
if time.time() - prev_time > ASYNC_INTERVAL:
prev_time = time.time()
plain_hello_world(name)
def task1():
loop = asyncio.get_event_loop()
task = loop.run_in_executor(None, plain_loop, "func", 1)
loop.run_until_complete(task)
def task2():
loop = asyncio.get_event_loop()
task = loop.run_in_executor(None, task1)
loop.run_until_complete(task)
if __name__ == "__main__":
task2()
问题:
我不明白为什么会发生这种错误。
仅运行Traceback (most recent call last):
File "asyncio_practice4.py", line 28, in <module>
task2()
File "asyncio_practice4.py", line 25, in task2
loop.run_until_complete(task)
File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
return future.result()
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "asyncio_practice4.py", line 18, in task1
loop = asyncio.get_event_loop()
File "/usr/lib/python3.6/asyncio/events.py", line 694, in get_event_loop
return get_event_loop_policy().get_event_loop()
File "/usr/lib/python3.6/asyncio/events.py", line 602, in get_event_loop
% threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'ThreadPoolExecutor-0_0'.
很好,但是运行task1()
却说没有当前的evet循环。 (但是我认为应该,我没有创建新线程)
有人知道发生了什么事吗?
假设我们只能在run_in_executor()
上工作,该如何解决?
注意:
调用2 task2()
的原因是因为上面的代码模仿了将第3个lib集成到异步代码中。
run_in_executor()
,plain_hello_world()
和plain_loop()
是lib中的代码,我无法修改。
假设task1()
运行100秒钟,而我不想等待它,因此我尝试在执行程序中运行它,就像其他普通函数如何与asyncio一起工作。
编辑: 根据答案,这里是有效的修订版本:
task1()
尽管我不确定它的“正确”或良好程度。
答案 0 :(得分:1)
我不明白为什么会发生这种错误。
之所以发生,是因为task1
假定它将在主线程(get_event_loop()
按需创建事件循环)或先前调用set_event_loop
的线程中运行设置事件循环。由于run_in_executor
在除主线程之外的其他线程中调用其函数,并且您的代码在调用set_event_loop()
之前没有调用,因此会出现错误。
假设task1()运行100s,而我不想等待它,所以我尝试在执行程序中运行它,就像其他普通函数如何与asyncio一起工作。
运行同步功能而不等待它不是asyncio要做的事情,这是常规线程的工作。例如:
def task1_bg():
def work():
asyncio.set_event_loop(asyncio.new_event_loop())
task1()
threading.Thread(target=work).start()
if __name__ == '__main__':
task1_bg()
# do something else...