【问题标题】:How to run 2 async functions forever?如何永远运行 2 个异步函数?
【发布时间】:2020-08-18 19:53:52
【问题描述】:

我正在尝试永远运行 2 个async 函数。有人能帮我吗?下面提供了我的代码和错误消息。

代码:

import websockets
import asyncio
import json
import time

async def time(loop):
    while True:
        millis = await int(round(time.time() * 1000))
        print(millis)
        await asyncio.sleep(0.001)

async def stream(loop):
    async with websockets.connect('wss://www.bitmex.com/realtime?subscribe=trade:XBTUSD') 
                    as websocket:
        while True:
            try:
                data = await websocket.recv()
                data = json.loads(data)
                print(data['data'][-1]['price'])
            except KeyError:
                pass
            except TypeError:
                pass

loop = asyncio.get_event_loop()

async def main():
    await asyncio.gather(loop.run_until_complete(stream(loop)), 
                         loop.run_until_complete(time(loop)))

if __name__ == "__main__":
    asyncio.run(main())

错误:

Exception has occurred: RuntimeError
Cannot run the event loop while another loop is running

【问题讨论】:

  • 你是如此接近 - 只需删除 loop.run_until_complete,一切都会正常。 (另外,在int 之前删除await,正如答案中所指出的那样。)

标签: python asynchronous python-asyncio


【解决方案1】:

嗯,您的 sn-p 代码几乎没有错误:

  1. 您不能将您的第一个函数命名为time,因为它会与time 内置函数产生冲突
  2. 如果你不打算使用loop 作为参数,为什么要传递它?没用。
  3. 如果函数不可等待,则不能 await 函数,即 int 是同步内置方法。

进行适当的更正,它将是这样的:

import websockets
import asyncio
import json
import time

async def another_name():
    while True:
        millis = int(round(time.time() * 1000))
        print(millis)
        await asyncio.sleep(0.001)

async def stream():
    async with websockets.connect('wss://www.bitmex.com/realtime?subscribe=trade:XBTUSD') 
                    as websocket:
        while True:
            try:
                data = await websocket.recv()
                data = json.loads(data)
                print(data['data'][-1]['price'])
            except KeyError:
                pass
            except TypeError:
                pass
            await asyncio.sleep(0.001) #Added

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    coros = []
    coros.append(another_name())
    coros.append(stream())
    loop.run_until_complete(asyncio.gather(*coros))

stream() 函数中的await asyncio.sleep(0.001) 行是强制性的,否则它永远不会让another_name() 函数运行。

【讨论】:

  • 你不能asyncio.run(asyncio.gather(...)),所以main确实有目的。
  • coros 变量的意义何在? asyncio.gather 精确地接受 awaitables 位置参数,因此您可以向它传递固定数量的参数,如 await asyncio.gather(one(), other()) 无需经历创建列表的麻烦。此外,用loop.run_until_complete() 替换asyncio.run(),这是运行异步代码的推荐方式,有点降级。
  • 你可以用你的知识改进答案,我们会感激你并向你学习
  • 但那将不再是你的答案,不是吗?根据框中的描述,cmets 是“用于建议改进”,这就是我的评论的意思。
猜你喜欢
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多