Python - 带有异步/协程的定时器 [英] Python - Timer with asyncio/coroutine

查看:76
本文介绍了Python - 带有异步/协程的定时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置一个计时器,该计时器将中断正在运行的进程并在它触发时调用协程.但是,我不确定实现这一目标的正确方法是什么.我找到了 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆