3 回答
TA贡献1801条经验 获得超15个赞
问题是您的except Exception
例外条款也会捕获取消并忽略它。更令人困惑的是,print(e)
在 a 的情况下只打印一个空行CancelledError
,这是输出中空行的来源。(将其更改为print(type(e))
显示发生了什么。)
要更正此问题,请更改except Exception
为更具体的内容,例如except asyncio.TimeoutError
. Python 3.8 中不需要此更改,它asyncio.CancelledError
不再派生自Exception
,而是派生自BaseException
,因此except Exception
不会捕获它。
TA贡献1856条经验 获得超17个赞
这似乎有效。这event是一个计数计时器,当它到期时它的cancels任务。
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()
TA贡献1842条经验 获得超12个赞
当您asyncio创建然后取消任务时,您仍然有需要“回收”的任务。所以你想要await worker它。然而,一旦你await取消了这样的任务,因为它永远不会给你返回预期的返回值,就会asyncio.CancelledError被提高,你需要在某个地方抓住它。
由于这种行为,我认为您不应该为每个取消的任务gather执行它们await,因为它们应该立即返回:
async def __aexit__(self,type,value,traceback):
await self._queue.join()
for worker in self._workers:
worker.cancel()
for worker in self._workers:
try:
await worker
except asyncio.CancelledError:
print("worker cancelled:", worker)
添加回答
举报