【问题标题】:How does the GC works with DI in .Net Core 2GC 如何与 .Net Core 2 中的 DI 一起工作
【发布时间】:2017-11-16 01:36:11
【问题描述】:

通常在使用实体框架时,我使用“using”子句:

using (var db = new dbcontext())
{
    var blabla = db.table.tolist();
}

现在,我们已将我们的平台迁移到 .Net Core (2) 中,因为有一个很棒的 DI 机制,我们决定使用它。现在,我们不再使用上述方式,而是在构造函数中获取 dbcontext 作为参数:

public MeaningfullNameController(dbcontext db)
{
    this.db = db;
}

而当另一个类需要使用 dbcontext 时,我们只需在第二个类的构造函数中传递上述 dbcontext 即可。

public class NewClass(dbcontext db)
{
    this.db = db;
}

这种情况让我思考,垃圾收集器如何处理这种情况? 在性能方面与第一种方法有区别吗?内存泄漏?等等

谢谢, 修罗

【问题讨论】:

  • 查看我的回答here。基本上它归结为 ASP.NET Core Abstractions 将在请求结束时处理作用域(每个请求)容器以及在它期间创建的所有一次性服务(瞬态和作用域服务,单例生存)

标签: c# .net asp.net-core garbage-collection .net-core


【解决方案1】:

在生命周期方面肯定存在差异。

在第一种方法中,您通过new 创建对象(并分配内存和它需要的任何其他资源)。 using 块的末尾将在其上调用 Dispose,释放所有非内存资源。当对象超出范围时,GC 可以看到它没有被使用并随时回收它。

在 DI 方法中,生命周期由 DI 框架管理。 DI 框架将分配它和Dispose 它。 DI 框架可以为应用程序的整个生命周期分配一次,每次调用 DI 支持方法一次或介于两者之间的任何时间。因此,寿命可能更长,甚至可能更长。如果对象存在的时间更长,则意味着 .NET Core 运行时系统分配它的频率较低,回收它的频率较低。它做的工作更少。但这意味着对象资源的使用时间更长:与数据库的连接和任何句柄将保持更长时间。如果您不只使用一次数据库,例如,在应用程序的生命周期内,并且您在整个生命周期内保持它处于活动状态,那么您只是在浪费您不需要的资源。

换句话说,没有一个简单的答案。对于经常使用的资源,与显式调用 new + Dispose 相比,使用具有每个方法调用生命周期的 DI 将涉及相似的工作量。对于其他类型的用途,这将取决于您在做什么以及什么对您的用例“更好”。

一般来说,这不是您应该尝试优化的东西,除非您知道这会导致性能问题。首先为开发者优化。

【讨论】:

  • 感谢您的出色回答。我们的流程是一个 Web api,因此每个请求的生命周期都相当短(据我所知),因此据我所知,DI 方法在这里会更好,因为 GC“工作较少”,与由于请求生命周期很短,因此数据库保持打开状态。我理解正确吗?
  • 明确一点,DI 方法取决于您如何配置服务。 Your choices are here。这与您的请求生命周期没有直接关系(除非您说您希望 DI 框架只为该时间创建一个对象)。为了让 DI 框架做最少的工作,请使用单例,这意味着对象在服务器的整个生命周期中都存在(不仅仅是您的请求)。
  • @omajid:EF Core 不适用于 ASP.NET Core 应用程序中的单例范围,因为同一个实例将用于多个请求和 EF Core (和之前的 EF 一样)不是线程安全的
  • @Tseng:似乎作用域在这里最合适:Singletone - 将在应用程序的整个生命周期内工作,因为 Tseng 说它不是线程安全的。瞬态 - 由于我将 dbcontext 传递给其他类,它会创建更多实例,从而导致性能下降。 Scoped,将在整个请求生命周期内创建。似乎是最好的选择。我做对了吗?
  • @ShaulZuarets;当您使用 AddDbContext 扩展方法时,Scoped 已经是默认生命周期。该方法有一个重载来更改它,但在大多数情况下它不是必需的。当您使用工厂模式创建上下文时(即导致租户仅在​​运行时已知),那么您必须自己处置它(即跟踪工厂内的 DbContext 实例并使工厂一次性,并在工厂获取时处置所有上下文处置)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2018-01-20
  • 2020-10-27
  • 2016-09-26
  • 2019-02-14
  • 1970-01-01
相关资源
最近更新 更多