【问题标题】:cannot access a disposed object Datacontext asp.net 5无法访问已处置的对象Datacontext asp.net 5
【发布时间】:2020-11-11 21:22:39
【问题描述】:

在 asp.net 5/core 中,我想使用异步延迟从我的数据库中删除一个项目。 我正在使用 DI 在课堂上注入我的 Datacontext (db)。

我创建了以下方法:

public async void DeleteItemAfterTimeAsync(int itemId, TimeSpan timeSpan)
{
    // give user time to fill out data
    await Task.Delay(timeSpan);
    var item = db.Items.FirstOrDefault(p => p.Id == itemId);
    if (item!= null && item.Status == someStatus)
    {
        db.Items.Remove(item);
        db.SaveChanges();
    }
}

在给定时间后,该方法按计划执行,但出现异常:“无法访问已处置的对象”,这可能是因为服务因延迟而被处置。 我应该在方法中解决我的数据上下文的新实例还是应该如何解决这个问题? 有任何想法吗? 感谢您提前提供帮助。

更新:

调用方法:

await DeleteItemAfterTimeAsync(item.Id, new TimeSpan(0, 1, 0));

更新方法:

public async Task DeleteItemAfterTimeAsync(int itemId, TimeSpan timeSpan)
{
   // give user time to fill out data
   await Task.Delay(timeSpan);
   var item = db.Items.FirstOrDefault(p => p.Id == itemId);
   if (item != null && item.Status == someStatus)
   {
      db.Items.Remove(item);
      db.SaveChanges();
   }    
}

db.Items.Remove(item) 发生异常;

【问题讨论】:

  • Datacontext 是如何注册的?作为瞬态?
  • 你试过用async Task代替async void吗?
  • 在 startup.cs: services.AddEntityFramework() .AddSqlServer().AddDbContext(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));跨度>
  • DbContext 的实例可能是每个请求创建的,因此一旦请求结束,它就会被处理掉。由于您的延迟,您尝试对已处置的对象进行操作(因为请求已经完成)
  • @Domysee 这确实有帮助。奇怪的事情:我可以毫无问题地执行 FirstOrDefault 调用,但是当我调用 db.Items.Remove(item) 时,我在输出窗口中看到 'Exception throw: 'System.ObjectDisposedException' in EntityFramework.Core.dll' 并且执行停止。 ..

标签: c# entity-framework async-await asp.net-core


【解决方案1】:

因为您的 DeleteItemAfterTimeAsync 方法是 async void,所以无法等待,并且在您使用 db 上下文时,它已经被释放了。

DeleteItemAfterTimeAsync 方法更改为async Taskawait

【讨论】:

  • 谢谢保罗,但我已经尝试过了。当我尝试调用 Remove(item) 时,仍然会在 EntityFramework.Core.dll 中出现“抛出异常:'System.ObjectDisposedException'”。查询id没问题...
  • 代码调用DeleteItemAfterTimeAsync?是async void吗? Somethng 在DeleteItemAfterTimeAsync 运行到最后之前在db 上调用Dispose
【解决方案2】:

我遇到了同样的问题。原因是我在调用堆栈中有一个更深的异步方法,它不是用'await'调用的。 (在您的示例中,不会使用 await 本身调用使用“await DeleteItemAfterTimeAsync”的方法)

使用的 DbContext 是在没有等待的情况下在对象调用中注入的依赖项。我猜 DbContext 是在我没有等待异步方法时被释放的。

现在你肯定已经解决了你的问题,但是检查调用堆栈可能是个好主意!

【讨论】:

    猜你喜欢
    • 2018-11-01
    • 1970-01-01
    • 2011-10-23
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多