Python - 带有异步/协程的定时器 [英] Python - Timer with asyncio/coroutine
问题描述
我正在尝试设置一个计时器,该计时器将中断正在运行的进程并在它触发时调用协程.但是,我不确定实现这一目标的正确方法是什么.我找到了 AbstractEventLoop.call_later 和 threading.Timer 但这些似乎都不起作用(或者我使用它们不正确).代码非常基本,如下所示:
I am trying to set a timer that will interrupt the running process and call a coroutine when it fires. However, I'm not sure what the right way to accomplish this is. I've found AbstractEventLoop.call_later, along with threading.Timer but neither of these seem to work (or I'm using them incorrectly). The code is pretty basic and looks something like this:
def set_timer( time ):
self.timer = Timer( 10.0, timeout )
self.timer.start()
#v2
#self.timer = get_event_loop()
#self.timer.call_later( 10.0, timeout )
return
async def timeout():
await some_func()
return
设置非阻塞定时器的正确方法是什么,它会在几秒钟后调用回调函数?能够取消计时器将是一种奖励,但不是必需的.我需要的主要东西是:非阻塞和成功调用协程.现在它返回一个错误,该对象不能被等待(如果我抛出一个等待)或者 some_func 从未被等待,并且预期的输出永远不会发生.
What is the correct way to set a non-blocking timer, that will call a callback function after some number of seconds? Being able to cancel the timer would be a bonus but is not a requirement. The major things I need are: non-blocking and successfully calling the co-routine. Right now it returns an error that the object can't be await'd (if I toss an await in) or that some_func was never await'd, and the expected output never happens.
推荐答案
创建 Task 使用 ensure_future 是常见的在不阻塞执行流程的情况下开始执行某些作业的方法.您还可以取消任务.
Creating Task using ensure_future is a common way to start some job executing without blocking your execution flow. You can also cancel tasks.
我为您编写了示例实现以供您开始:
I wrote example implementation for you to have something to start from:
import asyncio
class Timer:
def __init__(self, timeout, callback):
self._timeout = timeout
self._callback = callback
self._task = asyncio.ensure_future(self._job())
async def _job(self):
await asyncio.sleep(self._timeout)
await self._callback()
def cancel(self):
self._task.cancel()
async def timeout_callback():
await asyncio.sleep(0.1)
print('echo!')
async def main():
print('\nfirst example:')
timer = Timer(2, timeout_callback) # set timer for two seconds
await asyncio.sleep(2.5) # wait to see timer works
print('\nsecond example:')
timer = Timer(2, timeout_callback) # set timer for two seconds
await asyncio.sleep(1)
timer.cancel() # cancel it
await asyncio.sleep(1.5) # and wait to see it won't call callback
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
输出:
first example:
echo!
second example:
这篇关于Python - 带有异步/协程的定时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!