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

ABP 5.1.0事件处理器并发触发时抛出ObjectDisposedException异常

运行环境

使用ABP 5.1.0版本,基于.NET Core开发,首先定义泛型异步事件处理基类:

public class ItemAsyncEventBaseHandler<TEvent> : IAsyncEventHandler<TEvent>, ITransientDependency
    where TEvent : EventData
{
    // 基类内部实现省略
}

在此基类上实现自定义事件处理器CustomHandler,构造函数注入IUnitOfWorkManager与ISettingManager,重写HandleInternallyAsync方法处理ItemUpdatedEvent事件时,调用ISettingManager.ChangeSettingForApplicationAsync修改应用级配置,代码如下:

public class CustomHandler : ItemAsyncEventBaseHandler<EventData>
{
    private readonly IUnitOfWorkManager _unitOfWorkManager;
    private readonly ISettingManager _settingManager;

    public CustomHandler(
        IUnitOfWorkManager unitOfWorkManager,
        ISettingManager settingManager)
    {
        _unitOfWorkManager = unitOfWorkManager;
        _settingManager = settingManager;
    }

    public override async Task HandleInternallyAsync(ItemUpdatedEvent eventData)
    {
        await _settingManager.ChangeSettingForApplicationAsync("key", value.ToString());
    }
}

问题现象

单事件触发时功能表面运行正常,但短时间内连续触发两个不同条目对应的事件时,会抛出System.ObjectDisposedException异常(部分机器触发2次事件即可复现,部分机器需要更多次触发),提示无法访问已释放的MyDbContext对象,最终应用设置值更新失败,完整异常堆栈如下:

System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'MyDbContext'.
   at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.Set[TEntity]()
   at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase`3.GetQueryable()
   at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase`3.GetAllIncluding(Expression`1[] propertySelectors)
   at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase`3.FirstOrDefaultAsync(Expression`1 predicate)
   at Abp.Threading.InternalAsyncHelper.AwaitTaskWithPostActionAndFinallyAndGetResult[T](Task`1 actualReturnValue, Func`1 postAction, Action`1 finalAction)
   at Abp.Configuration.SettingStore.GetSettingOrNullAsync(Nullable`1 tenantId, Nullable`1 userId, String name)
   at Abp.Threading.InternalAsyncHelper.AwaitTaskWithPostActionAndFinallyAndGetResult[T](Task`1 actualReturnValue, Func`1 postAction, Action`1 finalAction)
   at Abp.Configuration.SettingManager.InsertOrUpdateOrDeleteSettingValueAsync(String name, String value, Nullable`1 tenantId, Nullable`1 userId)
   at Abp.Configuration.SettingManager.ChangeSettingForApplicationAsync(String name, String value)
   at Abp.Threading.InternalAsyncHelper.AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func`1 postAction, Action`1 finalAction)
   at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
   at Nito.AsyncEx.AsyncContext.<>c__DisplayClass15_0.<Run>b__0(Task t)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location where exception was thrown ---
   at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
   at Nito.AsyncEx.AsyncContext.Run(Func`1 action)

已尝试方案

曾尝试手动开启TransactionScopeOption.RequiresNew级别的新工作单元包裹配置修改逻辑,显式调用CompleteAsync提交工作单元,但问题仍未解决,代码如下:

public override async Task HandleInternallyAsync(ItemUpdatedEvent eventData) 
{
    using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
    {
        await _settingManager.ChangeSettingForApplicationAsync("key", value.ToString());
        await uow.CompleteAsync();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:57:22