首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么asyncio.wait不等待FIRST_COMPLETED

为什么asyncio.wait不等待FIRST_COMPLETED
EN

Stack Overflow用户
提问于 2015-11-07 18:12:04
回答 1查看 3K关注 0票数 3

我是Python3.5异步的新手。

在我下面的代码中,asyncio.wait()并不等待stop_future完成:

代码语言:javascript
复制
import asyncio
import datetime
from concurrent.futures import FIRST_COMPLETED


def stop():  # callback after 12 seconds

    print('stop', datetime.datetime.now())
    stop_future.set_result('Done!')


async def display_dt():

    while not stop_future.done():
        print('dt-1', datetime.datetime.now())
        # sleep 5 seconds or stop_future done
        asyncio.wait([await asyncio.sleep(5), stop_future],  return_when=FIRST_COMPLETED)
        print('dt-2', datetime.datetime.now())

    task = asyncio.Task.current_task()
    task.cancel()
    print(stop_future.result())


loop = asyncio.get_event_loop()
stop_future = asyncio.Future()
loop.call_later(12, stop)
loop.run_until_complete(display_dt())
loop.close() 

结果:

代码语言:javascript
复制
dt-1 2015-11-08 00:49:37.324582
dt-2 2015-11-08 00:49:42.325503
dt-1 2015-11-08 00:49:42.325503
dt-2 2015-11-08 00:49:47.326423
dt-1 2015-11-08 00:49:47.326423
stop 2015-11-08 00:49:49.327192  # async.wait stop_future not triggered
dt-2 2015-11-08 00:49:52.327343  # while loop finishes here
>>> Done!

更新:

下面是更新后的函数display_dt的代码,现在asyncio.wait可以工作了。

但我不明白为什么上面的代码与coro不工作??

代码语言:javascript
复制
@asyncio.coroutine    # decorator necessary? It works fine without 
def display_dt():

    while not stop_future.done():
        print('dt-1', datetime.datetime.now())
        yield from asyncio.wait([asyncio.sleep(5), stop_future], return_when=FIRST_COMPLETED)
        print('dt-2', datetime.datetime.now())

    task = asyncio.Task.current_task()
    task.cancel()
    print(stop_future.result())

结果:

代码语言:javascript
复制
dt-1 2015-11-08 01:19:06.289915
dt-2 2015-11-08 01:19:11.290836
dt-1 2015-11-08 01:19:11.290836
dt-2 2015-11-08 01:19:16.291757
dt-1 2015-11-08 01:19:16.291757
stop 2015-11-08 01:19:18.292525
dt-2 2015-11-08 01:19:18.292525  # async wait stop_future triggered
Done!

更新:需要 @asyncio.coroutine #装饰吗?

我在这伟大的一章上找到了答案

@asyncio.coroutine装饰师并不神奇。实际上,如果它装饰了一个生成器函数,并且没有设置PYTHONASYNCIODEBUG环境变量,那么装饰器实际上什么也不做。为了方便框架的其他部分,它只设置了一个属性_is_coroutine。完全可以用@asyncio.coroutine装饰的裸生成器使用异步。↩。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-08 06:31:15

您必须await .wait()协同线,而不是await您传递给.wait()的协同线。

代码语言:javascript
复制
async def display_dt():

    while not stop_future.done():
        print('dt-1', datetime.datetime.now())
        # sleep 5 seconds or stop_future done
        await asyncio.wait([asyncio.sleep(5), stop_future], return_when=FIRST_COMPLETED) # <----
        print('dt-2', datetime.datetime.now())

    task = asyncio.Task.current_task()
    task.cancel()
    print(stop_future.result())

现在,这相当于编辑,但使用本机协同(即async/await语法)。

更新显示结果:

代码语言:javascript
复制
dt-1 2015-11-08 13:14:21.910399
dt-2 2015-11-08 13:14:26.911320
dt-1 2015-11-08 13:14:26.911320
dt-2 2015-11-08 13:14:31.912240
dt-1 2015-11-08 13:14:31.912240
stop 2015-11-08 13:14:33.913009
dt-2 2015-11-08 13:14:33.913009
Done!
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33586072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档