You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django使用asgiref运行异步任务却实际同步执行的问题求解

问题核心原因

你对asgiref提供的async_to_sync工具的功能定位存在根本性误解,这是问题的根源:

  1. async_to_sync的作用是将异步函数包装为可在同步上下文调用的同步接口,调用时会阻塞当前线程,等待内部逻辑执行完成后再返回结果,完全不具备「后台异步执行、不阻塞主流程」的能力。
  2. 你传入async_to_sync的CallResource本身就是同步函数,这个包装操作没有任何实际意义,相当于直接同步调用了CallResource,自然会等待它执行完才走到下一行打印Answered。

解决方案

根据你的业务场景可以选择两类实现方式:

轻量场景(任务逻辑简单、无持久化/重试需求)

直接用Python内置的threading模块启动后台线程执行任务,主流程不会被阻塞,代码修改如下:

视图代码修改

import threading
from django.db import connection

@csrf_exempt
@api_view(('POST',))
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def IncomingMeliNotifications(request):
    print('--------------------------- Received ---------------------')
    notificacion = json.loads(request.body)
    # 启动后台线程执行任务,不阻塞主流程
    threading.Thread(target=CallResource, args=(notificacion,)).start()
    print('--------------------------- Answered ---------------------')

    return Response({}, template_name='assessments.html', status=status.HTTP_200_OK)

任务函数修改

在CallResource末尾主动关闭当前线程的数据库连接,避免连接泄漏:

def CallResource(notificacion):
    # 原有业务逻辑保留
    print('--------------------------- Secondary view ---------------------')
    # 新增:清理线程的数据库连接
    connection.close()
    return 'ok'

该方案修改成本极低,执行时序完全符合你的预期。

生产级场景(任务量大、需要重试/监控/调度能力)

建议使用成熟的Django异步任务队列实现,可选方案包括:

  • Celery:最主流的分布式任务队列,支持大量高级特性,适合中大型项目
  • Django Q:轻量原生Django集成的任务队列,配置简单
  • django-rq:基于Redis的轻量任务队列,性能优异

这类工具会将任务持久化存储到中间件,消费进程独立执行任务,不会受Web服务重启影响,也自带重试、失败告警等生产必备能力。

内容的提问来源于stack exchange,提问作者Francisco Ghelfi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 03:27:03