python - 如何在Python中的Threadpoolexecutor中运行异步函数

标签 python django asynchronous python-asyncio threadpoolexecutor

我有一个异步 get_forecastweather 函数,它为我提供 JSON 天气数据,我知道我们无法在同步中执行异步函数,但是我如何在单独的线程中执行它,需要帮助,提前致谢

def weather_detail(request):
    if request.method == 'GET':
        city_name = 'my_city'
        key = 'mykey'
        result = None
        with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
            response = executor.submit(get_forecastweather,city_name,key)
            result = response.result()
        print('Result from thread ',result)
        return render(request,'weather/weather_detail.html')

我收到的错误是

 RuntimeWarning: coroutine 'get_forecastweather' was never awaited
  response = wrapped_callback(request, *callback_args, **callback_kwargs)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

最佳答案

您可以编写一个小型包装函数,在单独的线程中运行异步例程并返回结果。您只需使用asyncio.run即可实现此目的。 ThreadPoolExecutor 机制将为您创建新线程,asyncio.run 方法将创建一个新的事件循环,运行它,返回结果,然后关闭循环。这是一个示例程序,我生成一个介于两个限制之间的随机整数,而不是您对天气的请求:

from concurrent.futures import ThreadPoolExecutor
import random
import time
import asyncio

# You would use weather_detail here
async def get_random(n0, n1):
    await asyncio.sleep(3.0)
    return random.randint(n0, n1)

def wrapper(coro):
    return asyncio.run(coro)

def main():
    print("Start", time.ctime())
    with ThreadPoolExecutor(max_workers=3) as executor:
        arglist = ((10, 20), (30, 40), (50, 60), (90, 100))
        coros = [get_random(n0, n1) for n0, n1 in arglist]
        for r in executor.map(wrapper, coros):
            print(r, time.ctime())
            
main()

# Output:
# Start Fri Sep 10 00:45:13 2021
# 15 Fri Sep 10 00:45:16 2021
# 40 Fri Sep 10 00:45:16 2021
# 52 Fri Sep 10 00:45:16 2021
# 99 Fri Sep 10 00:45:19 2021

我添加了时间戳来显示时间延迟,并证明三个线程正在并行运行。前三个对包装器的调用在 3 秒内完成,但第四个调用还需要 3 秒,因为只有三个工作线程。

关于python - 如何在Python中的Threadpoolexecutor中运行异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69114542/

相关文章:

javascript - 如何从异步调用返回响应?

Python代码格式化

javascript - 如何在现有的 django 网站上开始使用 React

django - 使用 Django 设置 Webpack

python - 无法在 django 中加载配置文件

java - servlet api 3.0 jar 中缺少异步方法?

javascript - 事件处理程序如何在 javascript 内部执行?

python - 属性错误 : 'str' object has no attribute 'errno'

python - 在后台运行 pika ioloop 或使用自定义 ioloop

python - 在一个文件中运行 Jython 和 Python