等待为 asyncio.Event 设置超时或事件
Wait for timeout or event being set for asyncio.Event
我有一个 class,其方法如下所示:
# self.stop_event -> threading.Event
def run(self):
while not self.stop_event.wait(3): # i.e. repeat every 3 sec
pass # do stuff
想法是,其中几个 运行 在它们自己的线程中,有时一个线程 stop_event.set()
,这自然会停止所有其他线程。我想为此切换到 asyncio,因为 run
中的任务主要是在睡觉和做 IO。因此,我必须:
# self.stop_event -> asyncio.Event
async def run(self):
while not self.stop_event.is_set():
await asyncio.sleep(3)
pass # do stuff
问题是 asyncio.Event
无法等待,所以当它被设置时,在方法完成之前最多等待 3 秒。这是一个问题,因为睡眠时间可能是几分钟。目前,我正在解决这个问题,方法是将 run
包装在 asyncio.Task
中,然后像 event_loop.call_soon(the_task.cancel)
.
一样取消它
请问有没有更好的方法实现上面的?有没有一种方法可以让我以某种方式等待 asyncio.Event
超时,类似于 threading.Event
?
Is there a way I can wait on an asyncio.Event
with a timeout somehow, similar to the threading.Event
?
asyncio.wait_for
支持方便地向任何等待的协程添加超时。 asyncio.Event
的 threading.Event.wait
超时功能的模拟可能如下所示:
async def event_wait(evt, timeout):
# suppress TimeoutError because we'll return False in case of timeout
with contextlib.suppress(asyncio.TimeoutError):
await asyncio.wait_for(evt.wait(), timeout)
return evt.is_set()
这使得 run
几乎与使用 threading.Event
的那个完全一样:
async def run(self):
while not await event_wait(self.stop_event, 3):
pass # do stuff
我有一个 class,其方法如下所示:
# self.stop_event -> threading.Event
def run(self):
while not self.stop_event.wait(3): # i.e. repeat every 3 sec
pass # do stuff
想法是,其中几个 运行 在它们自己的线程中,有时一个线程 stop_event.set()
,这自然会停止所有其他线程。我想为此切换到 asyncio,因为 run
中的任务主要是在睡觉和做 IO。因此,我必须:
# self.stop_event -> asyncio.Event
async def run(self):
while not self.stop_event.is_set():
await asyncio.sleep(3)
pass # do stuff
问题是 asyncio.Event
无法等待,所以当它被设置时,在方法完成之前最多等待 3 秒。这是一个问题,因为睡眠时间可能是几分钟。目前,我正在解决这个问题,方法是将 run
包装在 asyncio.Task
中,然后像 event_loop.call_soon(the_task.cancel)
.
请问有没有更好的方法实现上面的?有没有一种方法可以让我以某种方式等待 asyncio.Event
超时,类似于 threading.Event
?
Is there a way I can wait on an
asyncio.Event
with a timeout somehow, similar to thethreading.Event
?
asyncio.wait_for
支持方便地向任何等待的协程添加超时。 asyncio.Event
的 threading.Event.wait
超时功能的模拟可能如下所示:
async def event_wait(evt, timeout):
# suppress TimeoutError because we'll return False in case of timeout
with contextlib.suppress(asyncio.TimeoutError):
await asyncio.wait_for(evt.wait(), timeout)
return evt.is_set()
这使得 run
几乎与使用 threading.Event
的那个完全一样:
async def run(self):
while not await event_wait(self.stop_event, 3):
pass # do stuff