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

使用await触发ObjectDisposedException的C#异步代码问题及解决

问题:异步调用DbContext触发ObjectDisposedException,使用.Result却正常?

我有一个异步函数,调用DbContext时遇到问题:用await调用会触发ObjectDisposedException,但用.Result能得到正确结果。不过听说.Result会阻塞线程,不建议使用。

异常代码示例:

public async void AggrigateData()
{
    // some code
    var machineEvents = await _eventService.GetAllErrorEventsAsync();  // 无法正常运行
    var machineEvents = _eventService.GetAllErrorEventsAsync().Result; // 可正常运行
    var differentEventIds = machineEvents.Labels.Count; // 获取结果后立即使用
    // some code
}

请问该如何解决?这里用.Result是否有问题?我获取结果后会立即统计Labels数量。


补充背景

AggregateData由事件处理器调用,定时器不支持async Task,没法直接改成异步任务;之前尝试把DoWork改成async void,以为问题只是后移,没解决根本问题:

public Task StartAsync(CancellationToken stoppingToken)
{            
    _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromHours(1));

    return Task.CompletedTask;
}

private void DoWork(object state)
{
    machineEvaluationService.AggrigateData();
}

已解决的方案

修改代码后问题解决,调整后的代码如下:

// IHostedService的StartAsync,定时器部分保持不变
public Task StartAsync(CancellationToken stoppingToken)
{
    _timer = new Timer(DoWork, null, TimeSpan.Zero,
        TimeSpan.FromHours(1));

    return Task.CompletedTask;
}

// 将DoWork改为async void,内部await异步方法
private async void DoWork(object state)
{
    await machineEvaluationService.AggregateData();
}

// 改为async Task的AggregateData
public async Task AggrigateData()
{
    // some code
    var machineEvents = await _eventService.GetAllErrorEventsAsync();  
    var differentEventIds = machineEvents.Labels.Count; 
    // some code
}

原因解释

  1. 原代码问题根源:
    原AggregateData是async void方法,当同步的DoWork调用它时,方法执行到await就会立即返回,DoWork执行完毕后,当前作用域的DbContext可能被提前释放。后续await的GetAllErrorEventsAsync尝试访问已释放的上下文,就会抛出ObjectDisposedException。而.Result是阻塞调用,强制等待异步操作完成,DbContext在整个过程中保持存活,所以不会报错,但阻塞线程确实会带来性能和死锁风险。

  2. 修改后生效的原因:

    • 将DoWork改为async void(定时器回调场景是少数允许使用async void的场景),内部await AggregateData,确保AggregateData的异步操作被完整等待,不会提前返回。
    • AggregateData改为async Task,让异步流程的状态被正确跟踪,DbContext的生命周期可以覆盖到所有异步操作完成,避免被提前释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:40:38