asyncio结束脚本时完成



谁能告诉我如何(理解)使用asnycio来做到这一点:

  1. on_start-方法只在脚本启动时运行一次
  2. get_sensor_readings-当事件为True时方法运行
  3. evauluate_data-当事件为True时方法运行
  4. check_time-当事件为True时运行方法,查看事件是否存在仍然如此
  5. on_end-当事件在脚本结束前过期时,方法只运行一次

下面的脚本可以工作,只是模拟方法执行的时间。我使用randomawait asyncio.sleep(random.randint(3, 9))只是为了给上面的2、3、4的要点添加一些随机性。

import asyncio
from datetime import datetime as dt
from datetime import timedelta as td
import random
import time
class Program:
def __init__(self):
self.duration_in_seconds = 60
self.program_start = dt.now()
self.event_has_expired = False

async def on_start(self):
print("On Start Event Start! Applying Overrides!!!")
await asyncio.sleep(random.randint(3, 9))

async def on_end(self):
print("On End Releasing All Overrides!")
await asyncio.sleep(random.randint(3, 9))

async def get_sensor_readings(self):
print("getting sensor readings!!!")
await asyncio.sleep(random.randint(3, 9))   

async def evauluate_data(self):
print("checking data!!!")
await asyncio.sleep(random.randint(3, 9))   

async def check_time(self):
if (dt.now() - self.program_start > td(seconds = self.duration_in_seconds)):
self.event_has_expired = False
print("Event is DONE!!!")
else:
print("Event is not done! ",dt.now() - self.program_start)

async def main(self):
# script starts, do only once self.on_start()
await self.on_start()
print("On Start Done!")

while not self.event_has_expired:
await self.get_sensor_readings()
await self.evauluate_data()
await self.check_time()
# script ends, do only once self.on_end() when even is done
await self.on_end()
print('Done Deal!')

async def main():
program = Program()
await program.main()
asyncio.run(main())

我注意到的是脚本仍然在运行

On Start Event Start! Applying Overrides!!!
going into event intermission mode
getting sensor readings!!!
checking data!!!
Event is not done!  0:00:23.131918
getting sensor readings!!!
checking data!!!
Event is not done!  0:00:31.211425
getting sensor readings!!!
checking data!!!
Event is not done!  0:00:43.272416
getting sensor readings!!!
checking data!!!
Event is not done!  0:00:52.362870
getting sensor readings!!!
checking data!!!
Event is DONE!!!
getting sensor readings!!!
checking data!!!
Event is DONE!!!
getting sensor readings!!!
checking data!!!
Event is DONE!!!
getting sensor readings!!!
checking data!!!

任何提示都非常感谢。当Event is DONEon_end方法在脚本结束之前只运行一次时,我如何cancel协程?

这似乎可以工作:

import asyncio
from datetime import datetime as dt
from datetime import timedelta as td
import random
import time
class Program:
def __init__(self):
self.duration_in_seconds = 20
self.program_start = dt.now()
self.event_has_expired = False
self.canceled_success = False

async def on_start(self):
print("On Start Event Start! Applying Overrides!!!")
await asyncio.sleep(random.randint(3, 9))

async def on_end(self):
print("On End Releasing All Overrides!")
await asyncio.sleep(random.randint(3, 9))

async def get_sensor_readings(self):
print("getting sensor readings!!!")
await asyncio.sleep(random.randint(3, 9))   

async def evauluate_data(self):
print("checking data!!!")
await asyncio.sleep(random.randint(3, 9))   

async def check_time(self):
if (dt.now() - self.program_start > td(seconds = self.duration_in_seconds)):
self.event_has_expired = True
print("Event is DONE!!!")
else:
print("Event is not done! ",dt.now() - self.program_start)

async def main(self):
# script starts, do only once self.on_start()
await self.on_start()
print("On Start Done!")
while not self.canceled_success:
readings = asyncio.ensure_future(self.get_sensor_readings())
analysis = asyncio.ensure_future(self.evauluate_data())
checker = asyncio.ensure_future(self.check_time())

if not self.event_has_expired:
await readings   
await analysis           
await checker

else:
# close other tasks before final shutdown
readings.cancel()
analysis.cancel()
checker.cancel()
self.canceled_success = True
print("cancelled hit!")

# script ends, do only once self.on_end() when even is done
await self.on_end()
print('Done Deal!')

async def main():
program = Program()
await program.main()

调试单元:在await self.on_end()之前,您应该print一些东西。对于这个问题不重要,因为显然我们从来没有走到那一步。


你认为check_time改变了self.event_has_expired,然而while循环看不到它的变化。

我正在看文档。

建议使用同步原语,如线程中的条件变量或者可以从asyncio库中获取。

但是现在当我看到评论时,我看到@svex99正确地诊断出了问题——您进行了初始化将变量设置为False,然后再";change"你再做一次False。当然,while循环永远不会终止。

一旦你调整了这个细节,请告诉我们测试的情况。

最新更新