简体   繁体   English

asyncio create task and aiohttp, 'no running event loop'

[英]asyncio create task and aiohttp , 'no running event loop'

Im trying to make a Pyqt5 app with aiohttp request, and asyncio tasks.我正在尝试使用 aiohttp 请求和 asyncio 任务制作一个 Pyqt5 应用程序。 Im using quamash package too and it requires Python 3.7 so i installed this version.(it didn't work on Python 3.10) The main reason i use asyncio and quamash is because i want to do requests and without freezing the GUI of the app.我也在使用 quamash package,它需要 Python 3.7,所以我安装了这个版本。(它在 Python 3.10 上不起作用)我使用 asyncio 和 quamash 的主要原因是因为我想做请求而不冻结应用程序的 GUI。

I get this error when i click the Start button and close the app:单击“开始”按钮并关闭应用程序时出现此错误:

Task exception was never retrieved
future: <Task finished coro=<App.rotator() done, defined at C:\Users\Zsolt\Documents\python-example\stack_exmaple.py:37> exception=RuntimeError('no running event loop')>
Traceback (most recent call last):
  File "C:\Users\Zsolt\Documents\python-example\stack_exmaple.py", line 41, in rotator
    response = await get()
  File "C:\Users\Zsolt\Documents\python-example\stack_exmaple.py", line 51, in get
    async with session.get(pokemon_url) as resp:
  File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\client.py", line 1138, in __aenter__
    self._resp = await self._coro
  File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\client.py", line 533, in _request
    async with ceil_timeout(real_timeout.connect):
  File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\helpers.py", line 734, in ceil_timeout
    return async_timeout.timeout(None)
  File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\async_timeout\__init__.py", line 30, in timeout
    loop = _get_running_loop()
  File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\async_timeout\__init__.py", line 236, in _get_running_loop
    return asyncio.get_running_loop()
RuntimeError: no running event loop

Here is the full code:这是完整的代码:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import QKeySequence, QPalette, QColor
from PyQt5.QtCore import Qt
from PyQt5 import QtGui, QtCore
import asyncio
import aiohttp
import quamash
import os.path
import json
import sys

class App(QWidget):

    run = 0
    response = ''
    def __init__(self, loop):
        super().__init__()

        btn = QPushButton('Start', self)
        btn.resize(btn.sizeHint())
        btn.clicked.connect(self.start)

        self.setGeometry(200, 200, 700, 400)
        self.display = QLabel(self)
        self.display.resize(200, 500)
        self.display.move(1, 50)

        self.count = 0
        self.show()
        self.loop = loop
        self.tasks = []
        self.tasks.append(loop.create_task(self.rotator()))

    async def rotator(self):
        while await asyncio.sleep(0, True):
            if (self.run == 1):
                self.count += 1
                response = await get()
                self.display.setText(str(response))
                  
    def start (self):
        self.run = 1            

async def get():
    async with aiohttp.ClientSession() as session:
        pokemon_url = 'https://pokeapi.co/api/v2/pokemon/151'
        async with session.get(pokemon_url) as resp:
            pokemon = await resp.json()
            print(pokemon)
            return pokemon
      
app = QApplication(sys.argv)
app.setApplicationName("Sample ;)")

loop = quamash.QEventLoop(app)
asyncio.set_event_loop(loop)

with loop:
    window = App(loop)
    window.show()
    loop.run_forever()

If i comment out the response = await get() it works, it counts the self.count += 1 and it shows the variable on self.display.setText(str(self.count)) .如果我注释掉response = await get()它起作用,它会计算 self.count += 1 并在self.display.setText(str(self.count))上显示变量。 But i need to get it to work with the aiohttp request so it should print out the response from the request.但我需要让它与 aiohttp 请求一起工作,所以它应该打印出请求的响应。

TLDR; TLDR; replace quamash with qasync用 qasync 替换quamash

In asyncio, a task always exists when async code is executed.在 asyncio 中,执行异步代码时始终存在任务。 Like in a multithreaded program at least the main thread is present.就像在多线程程序中一样,至少存在主线程。 If quamash doesn't follow the rule -- it is not aiohttp problem.如果 quamash 不遵守规则——这不是 aiohttp 问题。

quamash is not maintained anymore, the latest release was made 3.5 years ago. quamash 不再维护,最新版本是 3.5 年前发布的。 The maintained successor is qasync which has no this bug and works with the latest aiohttp perfectly fine.维护的继任者是 qasync,它没有这个错误,并且可以完美地与最新的 aiohttp 配合使用。

FWIW, you may also use the qtinter package to replace quamash, which supports Python 3.7 to 3.11. FWIW,您也可以使用qtinter package 替换 quamash,它支持 Python 3.7 到 3.11。 ( Disclaimer : I'm the author of qtinter .) 免责声明:我是qtinter的作者。)

With qtinter the last few lines need to be changed to the following:使用qtinter ,最后几行需要更改为以下内容:

app = QApplication(sys.argv)
app.setApplicationName("Sample ;)")

with qtinter.using_asyncio_from_qt():
    window = App(asyncio.get_running_loop())
    window.show()
    app.exec()

I fixed the error by installing previous release of aiohttp Orignally i had aiohttp 3.8.1.dist installed and i knew it was working for me before on other version of aiohttp, so i looked up pypi.org/project/aiohttp/#history and turn out i had to uninstall aiohttp and install aiohttp==3.7.4.我通过安装以前版本的 aiohttp 修复了错误 最初我安装了 aiohttp 3.8.1.dist 并且我知道它之前在其他版本的 aiohttp 上对我有用,所以我查找了pypi.org/project/aiohttp/#history和原来我必须卸载 aiohttp 并安装 aiohttp==3.7.4。

Commands:命令:

pip uninstall aiohttp
pip install aiohttp==3.7.4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 asyncio/aiohttp - create_task() 阻止事件循环,在“此事件循环已在运行”中收集结果 - asyncio/aiohttp - create_task() blocks event loop, gather results in “This event loop is already running ” 结合 asyncio 和 aiohttp 时出现“RuntimeError:此事件循环已在运行” - "RuntimeError: This event loop is already running" when combine asyncio and aiohttp aiohttp:从正在运行的Web上调用asyncio应用程序:RuntimeError:此事件循环已在运行 - aiohttp: calling asyncio from a running web.Application: RuntimeError: This event loop is already running “运行时错误:此事件循环已在运行”; 在 python 3.6.5 中调试 aiohttp、asyncio 和 IDE“spyder3” - “RuntimeError: This event loop is already running”; debugging aiohttp, asyncio and IDE “spyder3” in python 3.6.5 Python asyncio - 如何创建任务列表并在事件循环中使用它? - Python asyncio - How to create task list and use it in the event loop? Flask asyncio aiohttp - RuntimeError:线程'Thread-2'中没有当前事件循环 - Flask asyncio aiohttp - RuntimeError: There is no current event loop in thread 'Thread-2' 如何在Python中使用aiohttp或asyncio创建并行循环? - How to create a parallel loop using aiohttp or asyncio in Python? 使用 asyncio 和 aiohttp 长时间运行的请求 - Long running requests with asyncio and aiohttp Asyncio 没有并行运行 Aiohttp 请求 - Asyncio not running Aiohttp requests in parallel Asyncio 锁在事件循环结束时获取任务 - Asyncio lock acquire task at end of event loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM