首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用asyncio.wait,我无法判断我的Event.wait任务是已完成的还是挂起的?

使用asyncio.wait,我无法判断我的Event.wait任务是已完成的还是挂起的?
EN

Stack Overflow用户
提问于 2020-11-13 12:41:55
回答 1查看 332关注 0票数 0

我在循环中接收消息,我希望循环是可取消的,所以我使用asyncio.Event对象作为循环何时退出的标志,如下所示:

代码语言:javascript
运行
复制
class MyThing:
    def __init__(self):
        self.quit = asyncio.Event

    async def loop(self):
        while True:
            t1 = self.quit.Wait()
            t2 = self.recv_message()
            done, pending = asyncio.wait([t1, t2], return_when=asyncio.FIRST_COMPLETED)

            if t1 in done:
                break

问题是t1 in done返回False,即使t1done中也是如此。在if语句之前粘贴一个断点,我可以看到t1如下所示:

代码语言:javascript
运行
复制
(Pdb) p t1
<coroutine object Event.wait at 0x7fcff72ed340>

但是done看起来是这样的:

代码语言:javascript
运行
复制
{<Task finished name='Task-95' coro=<Event.wait() done, defined at /usr/lib64/python3.8/asyncio/locks.py:296> result=True>}

当然,有很多方法可以解决这个问题。我可以写:

代码语言:javascript
运行
复制
if t2 not in done:

这似乎是正确的。我也可以检查一下self.quit.is_set()。但是为什么这个t1 in done测试不能像我预期的那样工作呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-13 13:21:48

但是为什么这个t1 in done测试不能像我预期的那样工作呢?

因为asyncio.wait接受任何类型的可访问对象,那些使用await关键字工作的对象,尤其是通过调用async def获得的对象。它返回的对象是asyncio.Future的子类,尤其是Task实例的子类。期货可以在后台运行,并支持一系列启用wait的方法,如add_done_callbackresult等。

asyncio.wait对它所接收的服务对象所做的第一件事是使用asyncio.ensure_future将它们转换为期货,这会将协同任务对象转换为任务,而通常,其他可服务性对象将转换为适当类型的未来。从那时起,它与期货一起工作,并归还它们。这种混乱甚至在文档中被描述,甚至促使开发人员放弃将非期货传递给asyncio.wait

使t1 in done能够工作的解决方法是让您调用ensure_future (或者当您知道自己正在处理协同机制时调用create_task ):

代码语言:javascript
运行
复制
t1 = asyncio.ensure_future(self.quit.Wait())
t2 = asyncio.ensure_future(self.recv_message())

另外,您不需要事件使循环可取消,您可以使用取消:

代码语言:javascript
运行
复制
class MyThing:
    def __init__(self):
        # cancel the loop_task with self.loop_task.cancel()
        self.loop_task = None

    async def loop(self):
        self.loop_task = asyncio.create_task(self._loop())
        await self.loop_task

    async def _loop(self):
        while True:
            await self.recv_message()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64821095

复制
相关文章

相似问题

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