栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

正常关闭异步协程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

正常关闭异步协程

什么
Task was destroyed but it is pending!
意思

如果目前您的程序已完成一些异步任务,但仍未完成,则会收到此警告。之所以需要此警告,是因为某些正在运行的任务可能无法正确释放某些资源。

有两种常见的解决方法:

  1. 您可以等待任务自己完成
  2. 您可以取消任务,等待任务完成

异步和阻止同步操作

让我们来看一下代码:

def shutdown(proto, loop):    print("Shutdown of DummyProtocol initialized ...")    proto.close()    time.sleep(2)    # ...

time.sleep(2)
-这行不会给协程足够的时间。它将冻结所有程序两秒钟。在这段时间内什么都不会发生。

发生这种情况是因为事件循环在您调用的同一进程中运行

time.sleep(2)
。您永远不要在异步程序中以这种方式调用长时间运行的同步操作。请阅读此答案以查看异步代码如何工作。

我们如何等待任务完成

让我们尝试修改

shutdown
功能。这不是异步函数,您不能
await
在其中添加任何内容。要执行一些异步代码,我们需要手动执行:停止当前正在运行的循环(因为它已经在运行),创建一些异步函数来等待任务完成,并传递此函数以在事件循环中执行。

def shutdown(proto, loop):    print("Shutdown of DummyProtocol initialized ...")    # Set shutdown event:     proto.close()    # Stop loop:    loop.stop()    # Find all running tasks:    pending = asyncio.Task.all_tasks()    # Run loop until tasks done:    loop.run_until_complete(asyncio.gather(*pending))    print("Shutdown complete ...")

您也可以取消任务并等待它们完成。有关详细信息,请参见此答案。

清理作业地点

我对信号并不陌生,但是您真的需要它来捕获CTRL-
C吗?无论何时

KeyboardInterrupt
发生的事件,都会在运行事件循环的地方逐行抛出(在代码中为
loop.run_forever()
)。我在这里可能是错的,但是处理这种情况的常用方法是将所有清理操作都置于
finally
阻塞状态。

例如,您可以看到

aiohttp
它是如何进行的:

try:    loop.run_forever()except KeyboardInterrupt:  # pragma: no branch    passfinally:    srv.close()    loop.run_until_complete(srv.wait_closed())    loop.run_until_complete(app.shutdown())    loop.run_until_complete(handler.finish_connections(shutdown_timeout))    loop.run_until_complete(app.cleanup())loop.close()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/464477.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号