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

无法排查‘Cannot access a disposed object’异常的原因与修复方案

问题分析与修复

错误根源

你遇到的System.ObjectDisposedException核心原因是**ProcessApplication方法未正确处理异步委托的执行**,导致外层代码误以为异步操作已完成,提前释放了依赖资源(如DbContext),而Lambda内部的异步逻辑仍在后台执行,最终访问了已被释放的对象。

具体问题点:

  • ProcessApplication声明返回Task,但内部未await异步的response委托调用,也未返回有效Task,本质是同步方法伪装成异步。
  • 外层await HelperService.ProcessApplication(...)实际等待的是一个立即完成的空Task,Lambda里的异步操作(如memberService.CreateMember、SaveAllMembers)会在后台继续执行。若DbContext为Scoped生命周期(比如Web应用场景),此时请求上下文可能已结束,DbContext被容器回收释放,后续调用SaveChangesAsync就会触发对象已释放异常。

修复步骤

1. 修正ProcessApplication方法的异步实现

修改方法以确保await异步委托执行,并正确返回Task:

public static async Task ProcessApplication(Application application, Func<string, List<string>, Task> response)
{
    List<string> reasons = [];

    CheckIncome(application, reasons);

    if (reasons.Count is 0)
        await response("APPROVED", ["Your application has been approved."]);
    else
        await response("DENIED", reasons);
}

2. 验证DbContext生命周期(关键)

确保DbContext生命周期覆盖整个异步操作流程:

  • 若为ASP.NET Core应用,DbContext默认是Scoped,需保证ProcessApplication及后续Lambda操作都在同一个请求Scope内执行,避免提前被回收。
  • 不要手动提前Dispose DbContext,交由容器管理其生命周期。

3. 优化Lambda内的异步逻辑(可选)

简化异步任务创建,避免不必要的嵌套await:

// 原membersTasks创建可简化,无需嵌套await
var membersTasks = application.Applicants.Select(applicant => memberService.CreateMember(applicant));
var members = (await Task.WhenAll(membersTasks)).ToList();

修复原理

修正后的ProcessApplication会真正等待Lambda内的异步操作完成后再返回,外层的await能确保所有数据库操作都在DbContext存活期间执行,彻底避免访问已释放对象的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:21:05