Python 在主循环中处理请求时,如何从django视图运行异步函数以在后台运行?
正如我在标题中所说,我希望在后台运行一个任务,处理一个大型数据库查询,同时处理来自前端的请求。我甚至可以用async/asyncio来实现吗?有人告诉我这是可能的 出于上下文的目的,我想做如下事情。另外请注意,我并不需要函数来告诉我什么时候完成了,尽管我确实想知道这是否可行,因为我只是检查.json文件是否最终被写入Python 在主循环中处理请求时,如何从django视图运行异步函数以在后台运行?,python,django,multithreading,asynchronous,Python,Django,Multithreading,Asynchronous,正如我在标题中所说,我希望在后台运行一个任务,处理一个大型数据库查询,同时处理来自前端的请求。我甚至可以用async/asyncio来实现吗?有人告诉我这是可能的 出于上下文的目的,我想做如下事情。另外请注意,我并不需要函数来告诉我什么时候完成了,尽管我确实想知道这是否可行,因为我只是检查.json文件是否最终被写入 def post_data_view(request): if request.method == 'POST': ... do_long
def post_data_view(request):
if request.method == 'POST':
...
do_long_query_in_the_background(some_data)
return HttpResponse('Received. Ask me in a while if I finished.')
def is_it_done_view(request):
if request.method == 'GET':
data = find_json()
if data:
return JsonResponse(data)
else:
return HttpResponse('Not yet dude...')
async def do_long_query_in_the_background(data):
# do some long processing...
# dump the result to a result.json
return
有人告诉我,使用async可以做到这一点,但我真的很难理解。就上下文而言,我试图将其简化很多,但即便如此,我还是发现自己不太明白发生了什么:
async def f():
while True:
print(0)
await asyncio.sleep(2)
asyncio.create_task(f())
即使我尝试的这段代码也失败了sys:1:RuntimeWarning:coroutine'f'从未被等待过,但它在控制台上确实可以工作,我不明白为什么会这样
我还想知道这是否是所有可能的和安全的线程可能吗
我对此感到非常沮丧,因为在其他线程中建议的一般解决方案似乎只是使用芹菜,但对于一个不太复杂的问题来说,这真的感觉像是一种过激的行为。async def f:
尽管如此:
打印0
等待asyncio.sleep2
asyncio.runf
asyncio中的run方法设置事件循环并创建任务对象,安排它运行并等待它完成,然后再执行任何其他代码
虽然异步编程看起来很简单,但它需要一种非常不同的编程方法,因为事情可能以任何顺序发生,并且您必须非常仔细地考虑什么顺序对函数的完成非常重要
不过,对于您的用例,您可能可以使用线程。您可以创建一个新线程,只要它在后台运行。在线程之间切换会导致性能下降,但如果大部分处理都在服务器端完成,用户可能会有更好的体验
这将永远运行,因为循环永远不会终止
从线程导入线程
从时间上导入睡眠
def f:
尽管如此:
打印0
等待asyncio.sleep2
def主:
打印“开始新线程…”
t=Threadtarget=f
t、 开始
打印“继续其他任务…”
睡觉
打印“还有更多事情要做…”
您需要使用aync定义视图函数。在您的情况下,它应该是:async def post_data_viewrequest:
在异步视图函数中:首先需要获取循环。然后在循环中创建一个任务。应该是:
如果您在end@el_osoSyntaxError:函数外部的“wait”听起来好像没有运行事件循环。您是否创建了事件循环?
async def post_data_view(request):
if request.method == 'POST':
....
loop = asyncio.get_event_loop()
loop.create_task(do_long_query_in_the_background(some_data))
return HttpResponse('Received. Ask me in a while if I finished.')