【问题标题】:Close asyncio loop关闭异步循环
【发布时间】:2021-07-27 08:41:09
【问题描述】:
import asyncio
import aiohttp
aut_token = ("token")
tasks = []
iter_flag = True
interval = 0
seq = 0
class WAPI:

    async def receiver(WAPI_S):
        async for msg in WAPI_S:
            global interval
            global seq
            data = msg.json()
            seq = data.get("s")
            if data.get("op") == 10:
                interval = data.get("d").get("heartbeat_interval") / 1000 
            if data.get("op") == 11:
                pass
            raise aiohttp.ClientError

    async def heartbeating(WAPI_S):
        while iter_flag:
            await WAPI_S.send_json({
                            "op": 1,
                            "d": seq
                        })
            
            await asyncio.sleep(interval)

    async def event_manager():
        loop = asyncio.get_running_loop()
        try:
            async with aiohttp.ClientSession() as session:
                async with session.ws_connect("url") as WAPI_S: 
                    task_receive = loop.create_task(WAPI.receiver(WAPI_S)); task_heartbeating = loop.create_task(WAPI.heartbeating(WAPI_S))
                    tasks.append(task_receive); tasks.append(task_heartbeating)
                    await asyncio.gather(*tasks)
        except aiohttp.ClientError:
            global iter_flag
            iter_flag = False
            await asyncio.sleep(interval)
            for task in tasks:
                task.cancel()
            try:
                loop.close()
            except:
                loop.stop()
                
asyncio.run(WAPI.event_manager())

我正在尝试通过关闭循环来捕获 ClientError 异常,但是,loop.close 会抛出“RuntimeError:事件循环在 Future 完成之前停止。”

如何正确实现拦截?

【问题讨论】:

    标签: python api asynchronous python-asyncio aiohttp


    【解决方案1】:

    您不需要手动跟踪您的任务,您可以简单地使用

    asyncio.all_tasks():

    Return a set of not yet finished Task objects run by the loop.

    然后是:

    pending = asyncio.all_tasks()
    c in pending:
        wait_for(c, timeout=5)
    
    

    此外,您正在尝试停止循环。 这是我最常使用的模式:

    async def main():
       <do some stuff>
    
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    except ExceptionYouWantToHandle:
        <cleaning up>
    finally:
        loop.stop()
    

    在 event_manager 中,您只需在获得执行或传递异常后返回

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-08
      • 2015-06-09
      • 2018-10-17
      • 2022-07-15
      • 2013-09-01
      • 2018-09-18
      • 1970-01-01
      相关资源
      最近更新 更多