【发布时间】:2020-04-21 16:14:19
【问题描述】:
我正在编写一个针对 dotnet 核心框架 3.1 的应用程序。我使用依赖注入来配置数据库上下文等。在我的 Program.cs 中,我有以下代码:
var host = new HostBuilder()
.ConfigureHostConfiguration(cfgHost =>
{
...
})
.ConfigureAppConfiguration((hostContext, configApp) =>
{
....
})
.ConfigureServices((hostContext, services) =>
{
...
services.AddDbContext<MyHomeContext>(options =>
{
options.UseNpgsql(hostContext.Configuration.GetConnectionString("DbContext"));
}, ServiceLifetime.Transient);
...
})
.ConfigureLogging((hostContext, logging) =>
{
...
})
.Build();
我将host 传递给另一个班级。在另一个类中,作为更长方法的一部分,我有以下代码:
using (var context = Host.Services.GetService(typeof(MyHomeContext)) as MyHomeContext)
{
StatusValues = context.Status.ToDictionary(kvp => kvp.Name, kvp => kvp.Id);
}
GC.Collect();
GC.Collect();
GC.Collect 电话用于测试/调查目的。在MyHomeContext 中,出于测试目的,我实现了析构函数和 Dispose() 的覆盖。
Dispose() 被调用,但析构函数永远不会被调用。
这会导致我创建的每个MyHomeContext 实例都会发生内存泄漏。
我错过了什么?我该怎么做才能确保MyHomeContext 的实例在我不再需要时被删除。
出于以下几个原因,我转向了这个工具:
- 我只需要很短时间的数据库连接。
- 我插入了大量数据(不是在上面简化的示例/测试代码中),导致 DbContext 保持很大的缓存。我希望处理对象会释放内存,但现在我只会让它变得更糟:(
当我用new MyHomeContext() 替换Host.Services.GetService(typeof(MyHomeContext)) as MyHomeContext 时,正在调用MyHomeContext 的析构函数。在我看来,依赖注入框架中的某些东西持有对该对象的引用。这是真的?如果是这样,我该如何告诉它释放它?
【问题讨论】:
-
不是这样的。您不应该依赖于被调用的析构函数。在Dispose 中释放您的托管和非托管资源。
-
嗨 Fildor,感谢您的帮助。我认为你没有很好地阅读这个问题。问题是/是该对象在使用 GetService 创建后没有被销毁。
-
其实没有。我确实读得足够好。接受的答案更详细地重申了我写的内容。您刚刚遇到了另一个导致您观察到的行为的问题,答案中也提到了这个问题,但我的评论中没有提到。我知道会有另一个因素,因此我没有写答案,而是发表评论。
标签: c# dependency-injection memory-leaks microsoft.extensions.hosting