【问题标题】:Prevent DbContext from being disposed until async task completes防止 DbContext 被释放,直到异步任务完成
【发布时间】:2021-10-13 06:23:05
【问题描述】:

我有一个 C# 核心 Web API 控制器(Microsoft.AspNetCore.Mvc.ControllerBase 的实现),它具有 API 方法 A 和 API 方法 B。A 是异步的,会触发并忘记异步工作线程。 B 是同步的。

A(及其工作线程)和 B 都使用实体框架从同一个数据库中读取和写入。但我遇到的问题是 DBContext 对象在 A 的工作线程完成之前被释放。

我知道一次性对象的所有者应该创建和处置它的原则。所以我考虑将 A 的 DBContext 包装在一个不是一次性的 Repository 类中,但这似乎违反了分析器规则:“CA1001:拥有一次性字段的类型应该是一次性的”-https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1001 但是如果我将 Repository 对象设为一次性,Dotnet当 A 返回时(但在其工作线程完成之前),核心会处理它。

我也考虑过将存储库设为单例,但这违反了 DbContext 对象应该是短暂存在的原则。

感谢您提出的任何建议!

【问题讨论】:

  • 是否可以选择使用托管服务?然后托管服务可以拥有自己的 DbContext 实例?
  • @MaartenDev 这是一个有用的建议,但从我所阅读的内容来看,托管服务在服务器的生命周期内运行,显然 DbContext 对象应该是短暂的。当然,我可以拥有一个负责启动工作线程的托管服务,但我认为这让我回到了原点。如果我误解了您的建议,请纠正我。

标签: entity-framework asp.net-core asynchronous dbcontext


【解决方案1】:

A 是异步的,会触发并忘记异步工作线程。

那么工作线程不得使用依赖注入管理的Scoped DbContext。相反,它应该在 using 块中创建 DbContext 实例,并在代码中显式管理其生命周期。

【讨论】:

  • @david-browne-microsoft 但正如我所提到的,VS 坚持我将工人标记为一次性,在这种情况下,工人本身在方法 A 返回时被处置(在工人完成工作之前) .
  • 我建议 DbContext 应该是在 using 块中声明的局部变量,而不是其他 Disposable 类型的成员。
  • @DavidBrowne-Microsoft 好的,将 DbContext 放在 using 块中是有意义的,但鉴于工作线程在多个方法中使用它,不应该在构造函数中实例化一次并用作类级变量?如果是这样,那不是让我回到开头,带着同样的分析员反对吗?
  • 你可以多次创建/销毁,或者在外部方法中创建并传递给其他方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-08
  • 2018-02-10
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
相关资源
最近更新 更多