为什么把 Scoped 注入到 Singleton 会导致内存泄露?

查看 66|回复 5
作者:drymonfidelia   
public class SingletonService
{
    private readonly DbContext _dbContext;
    public SingletonService(DbContext dbContext)
    {
        _dbContext = dbContext;
    }
}
public class SomeController
{
    private readonly SingletonService _singletonService;
    private readonly DbContext _dbContext;
    public SomeController(SingletonService singletonService, DbContext dbContext)
    {
        _singletonService = singletonService;
        _dbContext = dbContext;
    }
}
昨天晚上群里别人在讨论的问题,他们说这样注入会导致 SingletonService 里的 DbContext 释放不掉。我不是很理解,Singleton 每次运行都是同一个,SingletonService 里的 DbContext 永远只会创建一次,为什么会内存泄漏?
例子是 C#的,别的有依赖注入的语言应该也一样。
crysislinux   
我觉得没问题,又不会持续增长
timethinker   
就你贴出的这个例子而言,是的,DbContext 永远只会创建一次。
但是这种做法是有问题的,仅就这个例子而言,DbContext 不是线程安全的,这意味着当多个线程同时操作一个 DbContext 对象可能会引发数据竞争问题,破坏其内部状态的一致性。
微软官网是这样描述 DbContext 的生命周期的:The lifetime of a DbContext begins when the instance is created and ends when the instance is disposed. A DbContext instance is designed to be used for a single unit-of-work. This means that the lifetime of a DbContext instance is usually very short.
工作单元模式简单的来讲可以理解为对应于数据库的一个事务范围,在这个事务范围进行的操作会被追踪然后被提交。除非你确实有理由要一直保持一个 DbContext 的实例,并且考虑了线程安全问题,那么这么做就没什么问题。
cuso45h2o   
DbContext 是只会创建一次,但是因为它不会被 dispose ,如果它的代码有问题产生了大量 tracked entities ,这一个 DbContext 也会导致内存泄露。
irisdev   
@cuso45h2o 楼主,请教个问题,如果像 op 这样写,后续请求造成的 changes 会 append 在这个单例的 dbcontext 上吗
ch3nz   
会“可能导致内存泄漏和行为异常”而不是“一定导致”
你的例子是属于“一定导致”。
比如你给数据库一顿操作,dbContext track 了所有数据库变化,本该释放,但是被 singleton 持有而不能释放。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部