Flask asyncio aiohttp - 运行时错误: 线程 'Thread-2' 中没有当前的事件循环

5

最近读了关于Python并发的文章《Real Python - Python并发》

我的主要关注点是asyncio,所以我还比较新手。

使用asyncioaiohttp执行异步活动的代码块在直接运行时可以正常运行。

但是,当我将这段代码添加到我的Flask蓝图中时,就会引发以下错误:

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

为演示目的,我制作了一个演示Flask应用程序。 如果有人想测试它,请参考以下内容。

main.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个回答

7

编辑: 看起来你的代码是正确的。我通常写的方式不同。 但你可能正在运行Windows和Python 3.8。在Python 3.8上,Windows改变了默认事件循环策略,并且它相当有缺陷。你可以将旧的事件循环策略改回来:

更改为:

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

into:

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

问题出在哪里...你能再详细解释一下吗? - xaander1
当您在浏览器上刷新页面http://127.0.0.1:5000/demo/时,还会出现一堆错误raise RuntimeError('Event loop is closed') - xaander1
1
刷新时没有出现任何错误。但我认为这可能是由于Windows和Python 3.8+中的新事件循环策略存在漏洞。我看到很多东西都会发生错误,直到您将事件循环策略切换回旧版本。 (我编辑了我的答案) - Gerrit Geeraerts
我会看一下并回复你...有人意外格式化了我的Linux分区...不得不在Windows上测试(现在重新安装Linux)...如果在Linux上可以工作,那可能就没问题了。 - xaander1
修复了问题。 - xaander1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接