[英]How to stop an infinite event loop in asyncio with no name?
我有以下代码:
import asyncio
import time
class displayName:
def __init__(self, name, delay, exit = False):
self.name = name
self.delay = delay
self.exit = exit
async def start(self):
#displays name of object at regular time intervals
self.exit = False
print('starting display program...')
while True:
if self.exit == True:
print('ending display program')
break
print(self.name)
await asyncio.sleep(self.delay)
async def stop(self):
await asyncio.sleep(0)
self.exit = True
async def update_name(self, name):
await asyncio.sleep(0)
self.name = name
async def update_delay(self, delay):
await asyncio.sleep(0)
self.delay = delay
通常,我会执行:
display = displayName('Tom',5)
loop = asyncio.get_event_loop()
loop.create_task(display.start())
如果我想更改显示的名称,我会执行:
loop.create_task(display.update_name('Jerry'))
并停止循环我会执行:
loop.create_task(display.stop())
它将 display.exit 更改为 True 并结束循环。
但是,如果我尝试使用以下方法执行此代码:
asyncio.run(display.start())
那么我无法关闭循环!
我试过了:
loop1 = asyncio.get_running_loop()
loop1.close()
这什么也没做。 我可以进行键盘中断,但是每当我尝试使用 asyncio.run() 运行另一个任务时,我都会收到一条错误消息,指出无法从正在运行的事件循环中调用 asyncio.run()!
如何关闭这个活动循环,以便我可以再次使用 asyncio.run() ??!!!
如果这是相关的,我正在使用 Jupyter Notebook。
我搜索了互联网,发现以下似乎可行的技巧:
import nest_asyncio
nest_asyncio.apply()
当我运行此代码时,它似乎导致 Python “忘记”所有早期的 asyncio.run() 命令,现在我可以使用 asyncio.run() 正常运行其他代码块。
您的 class 没有错误。 错误是您使用run()
方法的方式。
当您执行asyncio.run(display.start())
时,程序将等待该协程完成。 因此,在这种情况下,您正在运行display.start()
这是一个无限循环。 这就是为什么协程运行时不能做任何其他事情的原因。
您必须在asyncio.run()
中调用一个管理所有指令的协程。 请看下面的代码:
import asyncio
class displayName:
def __init__(self, name, delay, exit = False):
self.name = name
self.delay = delay
self.exit = exit
async def start(self):
#displays name of object at regular time intervals
self.exit = False
print('starting display program...')
while True:
if self.exit == True:
print('ending display program')
break
print(f'name: {self.name} delay:{self.delay}')
await asyncio.sleep(self.delay)
async def stop(self):
await asyncio.sleep(0)
self.exit = True
async def update_name(self, name):
await asyncio.sleep(0)
self.name = name
async def update_delay(self, delay):
await asyncio.sleep(0)
self.delay = delay
async def main():
x = displayName('Tom', 1) #Create an instance of displayName
task = asyncio.create_task(x.start()) #Run x.start()
await asyncio.sleep(3) #waits 3 secs
await x.update_name('Chris') #Change name
await asyncio.sleep(3) #waits 3 secs
await x.update_delay(0.5) #Change delay time
await asyncio.sleep(3) #waits 3 secs
await x.stop() #Stop task
await task #Wait for task to end
asyncio.run(main())
print("This sentence will NOT be executed concurrently...")
print("This will be executed once asyncio.run() is done")
name: Tom delay:1
name: Tom delay:1
name: Tom delay:1
name: Tom delay:1
name: Chris delay:1
name: Chris delay:1
name: Chris delay:1
name: Chris delay:0.5
name: Chris delay:0.5
name: Chris delay:0.5
name: Chris delay:0.5
ending display program
This sentence will NOT be executed concurrently...
This will be executed once asyncio.run() is done
您提供的解决方案有效,但这根本不是推荐的方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.