Flask asyncio aiohttp - RuntimeError:线程'Thread-2'中没有当前事件循环

Posted

技术标签:

【中文标题】Flask asyncio aiohttp - RuntimeError:线程\'Thread-2\'中没有当前事件循环【英文标题】:Flask asyncio aiohttp - RuntimeError: There is no current event loop in thread 'Thread-2'Flask asyncio aiohttp - RuntimeError:线程'Thread-2'中没有当前事件循环 【发布时间】:2020-06-28 09:32:20 【问题描述】:

最近在看python并发realpython - python concurrency

我的主要关注点 asyncio 所以我很新。

使用asyncioaiohttp 执行异步活动的代码块在直接运行时运行良好。

但是,当我将代码添加到我的烧瓶蓝图时,它会引发此错误:

RuntimeError: There is no current event loop in thread 'Thread-2'

出于演示目的,我制作了一个演示烧瓶应用程序。以防万一有人想测试一下。

ma​​in.py

from flask import Flask
from my_blueprint import my_blueprint

#Define flask app
app = Flask(__name__)

#load blueprints
app.register_blueprint(my_blueprint,url_prefix='/demo')

#start flask
if __name__ == '__main__':
    app.run(debug=True)

my_blueprint.py

from flask import Blueprint,request, jsonify,abort,make_response
from flask import make_response
import asyncio
import time
import aiohttp

my_blueprint = Blueprint('my_blueprint', __name__)

@my_blueprint.route('/',methods=['GET'])
def home():
    #code block
    async def download_site(session, url):
        async with session.get(url) as response:
            print("Read 0 from 1".format(response.content_length, url))


    async def download_all_sites(sites):
        async with aiohttp.ClientSession() as session:
            tasks = []
            for url in sites:
                task = asyncio.ensure_future(download_site(session, url))
                tasks.append(task)
            await asyncio.gather(*tasks, return_exceptions=True)

    sites = ["https://www.jython.org","http://olympus.realpython.org/dice"]*20
    start_time = time.time()
    asyncio.get_event_loop().run_until_complete(download_all_sites(sites))
    duration = time.time() - start_time
    return jsonify("status":f"Downloaded len(sites) sites in duration seconds")
    #end of code block

【问题讨论】:

【参考方案1】:

编辑: 看起来你的代码是正确的。我习惯写不同的。 但是您可能正在运行 windows 和 python 3.8。这只是在 windows 上更改了 python 3.8 中的默认事件循环策略,而且它非常有问题。您可以改回旧的事件循环策略:

改变:

asyncio.get_event_loop().run_until_complete(download_all_sites(sites))

进入:

asyncio.set_event_loop(asyncio.SelectorEventLoop())
asyncio.get_event_loop().run_until_complete(download_all_sites(sites))

【讨论】:

出了什么问题...你能解释一下吗 在浏览器raise RuntimeError('Event loop is closed')刷新页面http://127.0.0.1:5000/demo/也会出现一堆错误 我在刷新时没有收到任何错误。但我认为这可能是 Windows 和 python 3.8+ 中新的事件循环策略的错误。在您将事件循环策略切换回旧策略之前,我看到了很多 stuf 错误。 (我编辑了我的答案) 我知道会看看然后回复你...有人不小心格式化了我的 linux 分区...不得不在 windows 上测试(现在重新安装 Linux)...如果它可以在 Linux 上运行可能没问题。 修复了问题。

以上是关于Flask asyncio aiohttp - RuntimeError:线程'Thread-2'中没有当前事件循环的主要内容,如果未能解决你的问题,请参考以下文章

asyncio/aiohttp 不返回响应

使用 aiohttp/asyncio 发出 100 万个请求 - 字面意思

Python学习---IO的异步[asyncio +aiohttp模块]

无法使用 asyncio/aiohttp 返回 404 响应

asyncio和aiohttp

asyncio 实现 aiohttp