在自定义 class 中为 Entity Framework 实施 IDisposable
Implementing IDisposable for Entity Framework in custom class
我用 Entity Framework 喜欢
public sealed class CacheManagementHelper
{
private readonly GJobEntities db = new GJobEntities();
public List<User> GetUsers()
{
return db.Users.ToList();
}
}
并且 MS Visual Studio 2019 建议关注
Warning CA1001 Implement IDisposable on 'CacheManagementHelper'
because it creates members of the following IDisposable types:
'GJobEntities'. If 'CacheManagementHelper' has previously shipped,
adding new members that implement IDisposable to this type is
considered a breaking change to existing consumers.
我在这里找到了一些线索
Entity Framework and calling context.dispose()
但是还不清楚我有没有实现IDisposable
。
感谢帮助!
But it is still unclear if I have implement IDisposable.
这是一个有几个答案的棘手问题:
- 不,你不应该。
- 是的,你应该。
- 不,您不必这样做。
总的来说:
IDisposable
对象应该在其生命周期结束时被释放。关于框架是否为您处理这个问题存在一些争论,但这是一种错误的方法。 (在底部,在 错误的方法 下,我将添加原因)
销毁的责任一般在创作者。所以; 如果你创建它,你就处置它。
@swdon 的评论就在这里;
The biggest issue I see in his code is db is public. I don't know who is responsible for getting rid of correctly. – swdon Aug 2 '19 at 7:07
这基本上就是为什么你不应该 public 非只读 IDisposable 成员字段。因为:当调用者覆盖它时,您将没有简单的方法来跟踪它,然后谁负责调用 Dispose
?
不,你不应该
国际奥委会
因此,您可能想要使用 IoC framework like Unity。这个 IoC 框架所做的是;它接管了创建对象的责任,因此,它也负责对象的处置。请注意:IoC 框架的目的不是成为工厂,它只是副作用之一。
因此,使用 IoC,您不会创建 自己的成员,您可以请求它。它可能看起来像这样:
private GJobEntities _context;
//constructor: this object can also be created by the IoC framework.
public CacheManagementHelper (GJobEntities context)
{
//set your field here
_context = context;
}
如果你使用这个,你不必在这里实现 IDispossable
因为你不是自己创建对象,你只是从框架请求上下文并让它调用 Dispose
方法。
为什么要提这个?因为它是 the future of .net.
的默认值
所以,使用这种方法;
不,你不应该实现 IDisposable,因为你没有创建 IDisposables,(但你应该摆脱 DbContext 的创建)。
是的,你应该
IDisposable
如果您需要坚持当前的模式 - 这是有道理的 - 您应该实施 IDisposable
。通过创建 IDispossable 成员,您负责处置它们。您可以通过实施 IDisposable
.
将其委托给 class 的创建者
public sealed class CacheManagementHelper : IDisposable
此对象的创建者现在创建了 IDisposable 对象,因此负责处置它。
您唯一的工作就是正确实现接口并释放您的资源。
通过阅读文档正确实现它是很不错的。我建议您使用此实现:Proper use of the IDisposable interface
所以,使用这种方法;
是的,您应该实施 IDisposable 并清理您的资源。
不,你不必
或者,
您可以在调用函数时创建上下文,将其保存在本地并将其放置在那里。通过这种方式,您将克服实现 IDisposable
的需要,因为上下文的创建者也在处理它。
//keeping it local
public List<User> GetUsers()
{
using (var db = new GJobEntities())
return db.Users.ToList();
}
所以,使用这种方法;
不,您不必实施 IDisposable,因为您没有创建 IDisposable 成员字段。
错误的方法
如果您阅读“Proper use of the IDisposable interface”,您就会知道,如果正确实施,您就可以安全地防止内存泄漏。
因此,有人可能会争辩说您 不需要 一起调用 Dispose
,因为垃圾收集器会为您完成。
这是一种误解。
问题如下:
- 1) 你不知道你调用的组件是否正确实现了。如果不处理它可能会泄漏(如果使用无人管理的内存)。
- 2)内存泄漏是;时间有关。惊奇咦?这样看:当你重新启动系统或重新启动应用程序时,内存又回来了。它不是永久性的。从过去开始,这就与应用程序的生命周期有关。但是关于多线程、无服务器编码等方面的发展确实需要我们稍微不同地看待它。 泄漏可能在特定时间范围内相关。一个很好的例子是高内存消耗图像处理或耗尽连接池。
所以,没有办法告诉垃圾收集器什么时候来清理东西。它可能不够快,无法在以下方面产生问题:打开的连接数、图形资源等。你正在泄漏,并依赖垃圾收集器来修复你的混乱,这是一种错误的方法。
最后的评论: EF DbContext 通过跟踪您的所有更改(它基本上是一个工作单元)在其生命周期内收集了大量资源。随着时间的推移,保持长期存在的 DbContext 可能会导致性能下降。所以,请注意这一点。
您必须通过实施 IDisposable
接口向消费者提供 class 处理内部 db
上下文的可能性:
public sealed class CacheManagementHelper : IDisposable
{
private readonly GJobEntities db = new GJobEntities();
public List<User> GetUsers()
{
return db.Users.ToList();
}
public void Dispose()
{
db.Dispose();
}
}
您还可以实施Finalizer
以确保资源将被释放,即使消费者端没有任何代码更改。
我用 Entity Framework 喜欢
public sealed class CacheManagementHelper
{
private readonly GJobEntities db = new GJobEntities();
public List<User> GetUsers()
{
return db.Users.ToList();
}
}
并且 MS Visual Studio 2019 建议关注
Warning CA1001 Implement IDisposable on 'CacheManagementHelper' because it creates members of the following IDisposable types: 'GJobEntities'. If 'CacheManagementHelper' has previously shipped, adding new members that implement IDisposable to this type is considered a breaking change to existing consumers.
我在这里找到了一些线索
Entity Framework and calling context.dispose()
但是还不清楚我有没有实现IDisposable
。
感谢帮助!
But it is still unclear if I have implement IDisposable.
这是一个有几个答案的棘手问题:
- 不,你不应该。
- 是的,你应该。
- 不,您不必这样做。
总的来说:
IDisposable
对象应该在其生命周期结束时被释放。关于框架是否为您处理这个问题存在一些争论,但这是一种错误的方法。 (在底部,在 错误的方法 下,我将添加原因)
销毁的责任一般在创作者。所以; 如果你创建它,你就处置它。
@swdon 的评论就在这里;
The biggest issue I see in his code is db is public. I don't know who is responsible for getting rid of correctly. – swdon Aug 2 '19 at 7:07
这基本上就是为什么你不应该 public 非只读 IDisposable 成员字段。因为:当调用者覆盖它时,您将没有简单的方法来跟踪它,然后谁负责调用 Dispose
?
不,你不应该
国际奥委会
因此,您可能想要使用 IoC framework like Unity。这个 IoC 框架所做的是;它接管了创建对象的责任,因此,它也负责对象的处置。请注意:IoC 框架的目的不是成为工厂,它只是副作用之一。
因此,使用 IoC,您不会创建 自己的成员,您可以请求它。它可能看起来像这样:
private GJobEntities _context;
//constructor: this object can also be created by the IoC framework.
public CacheManagementHelper (GJobEntities context)
{
//set your field here
_context = context;
}
如果你使用这个,你不必在这里实现 IDispossable
因为你不是自己创建对象,你只是从框架请求上下文并让它调用 Dispose
方法。
为什么要提这个?因为它是 the future of .net.
的默认值所以,使用这种方法;
不,你不应该实现 IDisposable,因为你没有创建 IDisposables,(但你应该摆脱 DbContext 的创建)。
是的,你应该
IDisposable
如果您需要坚持当前的模式 - 这是有道理的 - 您应该实施 IDisposable
。通过创建 IDispossable 成员,您负责处置它们。您可以通过实施 IDisposable
.
public sealed class CacheManagementHelper : IDisposable
此对象的创建者现在创建了 IDisposable 对象,因此负责处置它。
您唯一的工作就是正确实现接口并释放您的资源。
通过阅读文档正确实现它是很不错的。我建议您使用此实现:Proper use of the IDisposable interface
所以,使用这种方法;
是的,您应该实施 IDisposable 并清理您的资源。
不,你不必
或者,
您可以在调用函数时创建上下文,将其保存在本地并将其放置在那里。通过这种方式,您将克服实现 IDisposable
的需要,因为上下文的创建者也在处理它。
//keeping it local
public List<User> GetUsers()
{
using (var db = new GJobEntities())
return db.Users.ToList();
}
所以,使用这种方法;
不,您不必实施 IDisposable,因为您没有创建 IDisposable 成员字段。
错误的方法
如果您阅读“Proper use of the IDisposable interface”,您就会知道,如果正确实施,您就可以安全地防止内存泄漏。
因此,有人可能会争辩说您 不需要 一起调用 Dispose
,因为垃圾收集器会为您完成。
这是一种误解。
问题如下:
- 1) 你不知道你调用的组件是否正确实现了。如果不处理它可能会泄漏(如果使用无人管理的内存)。
- 2)内存泄漏是;时间有关。惊奇咦?这样看:当你重新启动系统或重新启动应用程序时,内存又回来了。它不是永久性的。从过去开始,这就与应用程序的生命周期有关。但是关于多线程、无服务器编码等方面的发展确实需要我们稍微不同地看待它。 泄漏可能在特定时间范围内相关。一个很好的例子是高内存消耗图像处理或耗尽连接池。
所以,没有办法告诉垃圾收集器什么时候来清理东西。它可能不够快,无法在以下方面产生问题:打开的连接数、图形资源等。你正在泄漏,并依赖垃圾收集器来修复你的混乱,这是一种错误的方法。
最后的评论: EF DbContext 通过跟踪您的所有更改(它基本上是一个工作单元)在其生命周期内收集了大量资源。随着时间的推移,保持长期存在的 DbContext 可能会导致性能下降。所以,请注意这一点。
您必须通过实施 IDisposable
接口向消费者提供 class 处理内部 db
上下文的可能性:
public sealed class CacheManagementHelper : IDisposable
{
private readonly GJobEntities db = new GJobEntities();
public List<User> GetUsers()
{
return db.Users.ToList();
}
public void Dispose()
{
db.Dispose();
}
}
您还可以实施Finalizer
以确保资源将被释放,即使消费者端没有任何代码更改。