3 回答

TA貢獻1801條經驗 獲得超16個贊
問題是您的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條經驗 獲得超13個贊
當您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)
添加回答
舉報