问题标签 [idisposable]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
9 回答
34628 浏览

.net - 垃圾收集器会为我调用 IDisposable.Dispose 吗?

.NET IDisposable 模式 意味着,如果您编写终结器并实现 IDisposable,则终结器需要显式调用 Dispose。这是合乎逻辑的,也是我在极少数需要终结器的情况下一直做的事情。

但是,如果我这样做会发生什么:

并且不要实现终结器或任何东西。框架会为我调用 Dispose 方法吗?

是的,我意识到这听起来很愚蠢,所有逻辑都暗示它不会,但我的脑后总是有两件事让我不确定。

  1. 几年前有人告诉我,它实际上会这样做,而且那个人在“了解他们的东西”方面有着非常可靠的记录。

  2. 编译器/框架会根据您实现的接口(例如:foreach、扩展方法、基于属性的序列化等)执行其他“魔术”操作,因此这也可能是“魔术”是有道理的。

虽然我已经阅读了很多关于它的东西,并且暗示了很多东西,但我从来没有能够找到一个明确的“是”或“否”的答案来回答这个问题。

0 投票
7 回答
2046 浏览

c# - 如何在 C# 中执行 C++ 风格的析构函数?

我有一个带有Dispose函数的 C# 类IDisposable。它旨在在using块内使用,因此可以立即释放它处理的昂贵资源。

问题是在调用之前抛出异常时发生了错误Dispose,而程序员忽略了使用usingor finally

在 C++ 中,我从来不用担心这个。对类的析构函数的调用将自动插入到对象作用域的末尾。避免这种情况发生的唯一方法是使用 new 运算符并将对象保存在指针后面,但这需要程序员额外的工作不是他们会偶然做的事情,比如忘记使用using.

有什么方法using可以在 C# 中自动使用块?

非常感谢。

更新:

我想解释一下为什么我不接受终结者的答案。这些答案本身在技术上是正确的,但它们不是 C++ 风格的析构函数。

这是我发现的错误,简化为基本要素...

使用FXCop是一个很好的建议,但如果这是我唯一的答案,我的问题将不得不成为 C# 人的请求,或者使用 C++。二十个嵌套 using 语句有人吗?

0 投票
8 回答
12604 浏览

c# - 从派生类自动调用 base.Dispose()

编辑 - 新问题

好的,让我们更笼统地重新表述这个问题。

使用反射,有没有办法在运行时动态调用您可能覆盖的基类方法。您不能在编译时使用“base”关键字,因为您无法确定它是否存在。在运行时,我想列出我的祖先方法并调用祖先方法。

我尝试使用 GetMethods() 等,但它们返回的只是指向该方法的最派生实现的“指针”。不是基类的实现。

背景

我们正在使用 C# 3.0 开发一个具有相对较大的类层次结构的系统。其中一些类,在层次结构中的任何位置,都具有需要释放的资源,它们实现了IDisposable接口。

问题

现在,为了方便代码的维护和重构,我想为实现 IDisposable 的类找到一种方法,如果任何祖先也实现 IDisposable ,则“自动”调用base.Dispose(bDisposing) 。这样,如果层次结构中较高的某个类开始实现或停止实现 IDisposable,它将自动得到处理。

问题有两个方面。

  • 首先,查找是否有任何祖先实现了 IDisposable。
  • 其次,有条件地调用 base.Dispose(bDisposing)。

第一部分,关于实现 IDisposable 的祖先的发现,我已经能够处理。

第二部分是棘手的部分。尽管我付出了所有努力,但我还是无法从派生类中调用 base.Dispose(bDisposing)。我所有的尝试都失败了。它们要么导致编译错误,要么调用错误的 Dispose() 方法,这是最衍生的方法,因此永远循环。

主要问题是,如果没有实现它的祖先之类的东西,您实际上不能在代码中直接引用 base.Dispose() (请注意,可能还没有实现 IDisposable 的祖先,但我希望派生代码准备好何时以及如果将来发生这样的事情)。这给我们留下了反射机制,但我没有找到合适的方法。我们的代码充满了先进的反射技术,我想我没有错过任何明显的东西。

我的解决方案

我最好的办法是在注释代码中使用一些条件代码。更改 IDisposable 层次结构会破坏构建(如果不存在 IDisposable 祖先)或引发异常(如果存在 IDisposable 祖先但未调用 base.Dispose)。

这是我发布的一些代码,向您展示我的 Dispose(bDisposing) 方法的外观。我将此代码放在整个层次结构中所有 Dispose() 方法的末尾。任何新类都是从也包含此代码的模板创建的。

所以,我问有没有办法自动/有条件地调用 base.Dispose() ?

更多背景

应用程序中还有另一种机制,其中所有对象都注册到一个主类。该类检查它们是否实现了 IDisposable。如果是这样,它们将由应用程序正确处理。这避免了使用类来处理自己调用 Dispose() 的代码。因此,将 IDisposable 添加到没有 IDisposable 祖先历史的类中仍然可以正常工作。

0 投票
4 回答
11719 浏览

vb.net - VB.NET - 实现 IDisposable 时是否应该添加 Finalize 方法?

在 Visual Studio 中,当我键入“ Implements IDisposable”行时,IDE 会自动添加:

  • 成员disposedValue变量
  • 一种Sub Dispose() Implements IDisposable.Dispose
  • 一种Sub Dispose(ByVal disposing As Boolean)

应该不理Dispose()会,清理代码应该放在Dispose(disposing).

然而Dispose Finalize Pattern说你也应该重写Sub Finalize()call Dispose(False)。为什么 IDE 也不添加这个?我必须自己添加它,还是以某种方式隐式调用它?

编辑:知道为什么 IDE 会自动添加 80% 的所需内容但忽略 Finalize 方法吗?这种功能的全部意义不在于帮助您不要忘记这些事情吗?

EDIT2:谢谢大家的出色回答,现在这很有意义!

0 投票
6 回答
3740 浏览

c# - 终结器和处置

我有一个名为的类BackgroundWorker,它有一个不断运行的线程。要关闭这个线程,一个名为stopto 的实例变量需要是true.

为了确保在使用完类时释放线程,我添加IDisposable了一个调用Dispose(). 假设stop = true确实会导致该线程退出,那么这个 sippet 是否正确?Dispose从终结器调用很好,对吗?

Dispose如果object继承,终结器应该总是调用IDisposable,对吗?

0 投票
5 回答
130531 浏览

c# - 我什么时候应该使用 GC.SuppressFinalize()?

在 .NET 中,我应该在什么情况下使用GC.SuppressFinalize()?

使用这种方法能给我带来什么好处?

0 投票
8 回答
47355 浏览

c# - 如何判断 IDisposable 对象引用是否已释放?

有没有一种方法或其他一些轻量级的方法来检查引用是否是对已处理对象的引用?

PS - 这只是一个好奇(睡得好,不是在生产代码中)。是的,我知道我可以ObjectDisposedException在尝试访问对象的成员时捕捉到。

0 投票
11 回答
14368 浏览

c# - Intercepting an exception inside IDisposable.Dispose

In the IDisposable.Dispose method is there a way to figure out if an exception is being thrown?

If an exception is thrown in the using statement I want to know about it when the IDisposable object is disposed.

0 投票
4 回答
2034 浏览

c# - Winforms 处理 IDisposable

有没有人有关于正确使用 dispose 和 IDisposable 的好文章或教程。我试图向一些初级开发人员解释这一点,并希望获得一些额外的材料、示例等。

0 投票
4 回答
4437 浏览

.net - 如何对 IDisposable 进行单元测试?

我正在研究一段库代码IDisposable。托管路径 (via using) 易于测试。不过,我想知道终结器:调用System.GC.Collect()足以强制终结器运行吗?