当前位置: 首页 > 知识库问答 >
问题:

传递协程到AbstractEventLoop.call_later

宗冠宇
2023-03-14

以下是我正在尝试使用的代码:

>>> import asyncio
>>> async def foo(loop, iv):
...     await asyncio.sleep(1, loop=loop)
...     print(f'done: {iv}')
...     
>>> loop = asyncio.get_event_loop()
>>> loop.call_later(2, foo, loop, 10)
<TimerHandle when=36395.554089349 foo(<_UnixSelecto...e debug=False>, 10) at <input>:1>
>>> loop.run_forever()

(Python 3.6)

基本上,foo()函数有一些链式的async调用,所以这个方法必须是async,因为需要等待链式调用。然而,此方法是在延迟后触发的,当运行此代码时,会出现以下问题:

/usr/lib64/python3。6/异步IO/事件。py:127:RuntimeWarning:coroutine'foo'从未被期待过_回调(*self.\u args)

在以后的call\u中处理此async调用的正确方法是什么?

共有1个答案

常博裕
2023-03-14

call\u later()仅支持回调(常规函数);你根本无法通过一个合作项目。

如果您想延迟协程,您有两个选项;要么通过让协程在开始时Hibernate来延迟协程,要么从call_later()调用asyncio.create_task()安排它运行。

使用asyncio。sleep()在例程开始时,可以让循环直接执行它:

async def foo(iv):
    # delay start of the work
    await asyncio.sleep(2)

    # rest of your coroutine

您可以很容易地使用包装器协程来实现这一点:

async def await_coro_later(delay, coro, *args, **kwargs):
    await asyncio.sleep(delay)
    await coro(*args, **kwargs)

如果您使用asyncio。创建任务()

# create a task for foo(10) later
loop.call_later(2, asyncio.create_task, foo(10))

任何一种技术的演示:

>>> import asyncio
>>> async def foo(iv, start):
...     await asyncio.sleep(1)
...     offset = asyncio.get_running_loop().time() - start
...     print(f'done ({offset:.3f}s): {iv}')
...
>>> async def await_coro_later(delay, coro, *args, **kwargs):
...     await asyncio.sleep(delay)
...     await coro(*args, **kwargs)
...
>>> async def demo():
...     loop = asyncio.get_running_loop()
...     start = loop.time()
...     loop.call_later(2, asyncio.create_task, foo('cb_to_create_task', start))
...     await await_coro_later(5, foo, 'coro_later', start)
...
>>> asyncio.run(demo())
done (3.004s): cb_to_create_task
done (6.006s): coro_later

 类似资料:
  • 问题内容: 我在Linux中有一个多线程程序。我想在某些内存区域中查看它们是否已在特定时间段内写入。为此,我仅授予对这些内存页面的读取访问权限,并为SIGSEGV安装信号处理程序。现在我的问题是,每个线程都会自己调用信号处理程序。假设线程1写入某个禁止的内存区域,它是执行信号处理程序的区域吗? 问题答案: 首先 信号处理是全过程的;进程中的所有线程对于每个信号共享相同的配置。如果一个线程使用sig

  • 我尝试在Scala中实现一个StateMachine,但是我遇到了一个关于类型系统的问题,这让我相当困惑。在下面的代码中,我需要让guard函数接受StateMachine的预期子类的参数。不幸的是,由于FunctionN参数的类型参数是逆变的,我不确定如何完成此操作。

  • 我在编写一个应用程序时遇到了一些问题。它的工作是用线来解决迷宫。一个线程开始,对于每个分支,它调用另一个类中的静态方法,传递另一个线程需要的参数,然后为每个路径启动线程。我的输出都搞乱了,我不确定这是多线程问题还是引用的问题。下面是一些代码(每个线程都有一个类的新实例): 和返回ValidPaths的方法 CheckEnvirondings使用传递给子级的深度副本(通过构造函数)来验证子级可以采用

  • Spark 的 API 很大程度上依靠在驱动程序里传递函数到集群上运行。这里有两种推荐的方式: 匿名函数 (Anonymous function syntax),可以在比较短的代码中使用。 全局单例对象里的静态方法。例如,你可以定义 object MyFunctions 然后传递 MyFounctions.func1,像下面这样: object MyFunctions { def func1(

  • 异常: 传递流程 基于上述注释观察并理解异常传递流程: <?php function g1() { throw new \Exception(); yield; } // a2 -> b2 -> (new AsyncTask(g1()))->begin(); function g2() { yield; throw new \Exception(); } //

  • 我想知道将字符串从Java程序传递到Python程序的最简单方法是什么。原因是我使用boilerpipe从web中提取一些文本,然后通过Java程序进行分析,但我还必须使用模式进行一些语义搜索。这只适用于python。 我不需要从python程序中获取结果,只需要python程序可以获取字符串。 我首先考虑让我的python程序听一段对话。txt文件,而java为其提供字符串,但我认为这太难了。