【问题标题】:Python asyncio not executingPython异步未执行
【发布时间】:2021-11-22 13:33:00
【问题描述】:

我并不是真正的 Python 专家,如果这真的很明显,请原谅。我正在尝试使用 asyncio 运行脚本。相关代码:

import websockets
import asyncio

stream = websockets.connect(<resource_uri>)

async def main():
    async with stream as receiver:
        while True:
            data = receiver.recv()
            # do stuff


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

当我运行它时,我得到:

DeprecationWarning:没有当前的事件循环 loop = asyncio.get_event_loop()

同样,使用

''' 循环 = asyncio.get_running_loop() '''

相反,我得到了

RuntimeError: 没有正在运行的事件循环。

有什么想法吗?我想这与 main() 没有在正确的线程中运行有关...

我正在使用 Python 3.10。

【问题讨论】:

标签: python python-asyncio


【解决方案1】:

试试这个,在 3.8 上为我工作(可能最初是从比我更聪明的人那里得到的,把它贴在这里!!)

 try:
    loop = asyncio.get_running_loop()
 except RuntimeError:  # 'RuntimeError: There is no current event loop...'
    loop = None

 if loop and loop.is_running():
     print('Async event loop already running. Adding coroutine to the event loop.')
     tsk = loop.create_task(main())
     # ^-- https://docs.python.org/3/library/asyncio-task.html#task-object
     # Optionally, a callback function can be executed when the coroutine completes
     tsk.add_done_callback(
        lambda t: print(f'Task done with result = {t.result()}'))
 else:
    print('Starting new event loop')
    asyncio.run(main())

【讨论】:

  • 正如你所写,这是从某处复制而来的,它解决的问题与所要求的不同。
  • 因此,在您看来,它不会 (i) 检测(并处理)实际“没有正在运行的事件循环”并且 (ii) 如果存在“没有启动事件新循环”没有正在运行的事件循环”?这是一个有趣的方法来解决一个与被问到的不同的问题。
  • 如果您在程序启动后首先启动事件循环,那么您无需测试它是否尚未运行。
  • 不幸的是,如果我尝试这样做,我经常会被告知有一个事件循环已经在运行。我不知道窗户是否没有正确清理自己。无论哪种方式,我都需要上面的东西来运行我想要的。
【解决方案2】:

较新的代码应该只使用 asyncio.run(main()) - 这将自动创建一个新的实例循环并在可等待对象上“运行直到完成”。

【讨论】:

  • 感谢您的快速回复!我现在得到: RuntimeError: Task /main.py:22> cb=[_run_until_complete_cb() at>/Library/Frameworks/ Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py:184]> 在 /Library/Frameworks/Python.framework/ 获得了 Future ._call_check_cancel() Versions/3.10/lib/python3.10/asyncio/futures.py:384]> 附加到不同的循环
  • 答案是正确的 IMO。必须有另一个问题负责RuntimeError
  • 是的,我确定一定有。
  • 问题可能是,一旦您调用 asyncio.run(main()) 一次,您就启动了一个事件循环,该循环不会必要(以我的经验)带着新的执行。也许这是因为我的环境是垃圾或什么的。因此(正如我经常遇到的那样)第二次执行希望在进一步的循环中开始进一步运行 main(),因此发出警告。
  • 嗯。只是阅读,较新的方法应该自行清理。类/.py“流”是从“流”分叉出来的吗?
【解决方案3】:

websockets 和 Python 3.10 似乎存在问题。看来我得想办法解决了。感谢您的宝贵时间!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 2016-02-03
    相关资源
    最近更新 更多