问题标签 [suppressfinalize]
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.
c# - 多次调用 SuppressFinalize
GC.SuppressFinalize(object)
多次调用有什么缺点吗?dispose 模式的
受保护Dispose(bool)
方法检查它是否在之前被调用,但在公共方法中没有这样的检查。Dispose()
Dispose()
实例的方法可以MyClass
多次调用吗?
dependency-injection - 在实现 IDependencyResolver 和 IDependencyScope 的类中应该如何对 Dispose 进行编码?
我在我的 Web API 项目上运行了代码分析,我在其中尝试使用 Castle Windsor 实现 IoC 和 DI,它发现了四个问题。它发现的四件事都在 WindsorDependencyResolver 中,并且所有四件事都是“正确实施 IDisposable”,即:
0) CA1063 正确实现 IDisposable 在“WindsorDependencyResolver”上提供可覆盖的 Dispose(bool) 实现或将类型标记为密封。对 Dispose(false) 的调用应该只清理本机资源。对 Dispose(true) 的调用应该清理托管资源和本机资源。
这指向这行代码:
1) CA1063 正确实现 IDisposable 修改“WindsorDependencyResolver.Dispose()”,使其调用 Dispose(true),然后对当前对象实例(Visual Basic 中的“this”或“Me”)调用 GC.SuppressFinalize,然后返回。
这指向这行代码:
2) 与 O 相同,但适用于 WindsorDependencyScope : IDependencyScope 类。
3) 与 1 相同,但 ""
我从 Castle Windsor 在线文章中获得了我正在尝试的代码,主要来自这篇文章。该文件的完整代码是:
缓和代码分析工具的最佳方法是什么?
c# - 这是如何“正确实施 IDisposable”?
我对我的一个项目进行了代码分析,它给了我两个手指,即:
CA1063 正确实现 IDisposable 在“UserStore”上提供可覆盖的 Dispose(bool) 实现或将类型标记为密封。对 Dispose(false) 的调用应该只清理本机资源。对 Dispose(true) 的调用应该清理托管资源和本机资源。
...在这行代码上:
...和这个:
CA1063 正确实现 IDisposable 修改“UserStore.Dispose()”,使其调用 Dispose(true),然后对当前对象实例(Visual Basic 中的“this”或“Me”)调用 GC.SuppressFinalize,然后返回。
...在我的空处置:
我可以这样用一只石化的土块刺杀两只鸟吗?
? 这是它的暗示吗?
更新
回答我的问题(有点),显然不是 - 我想我只是添加代码,看看代码分析是否会反馈渴望的“'NRBQ.API.UserStore.Dispose()':不合适发现覆盖的方法“
c# - 拥有终结器的开销 - 在 Dispose 中有/没有 SuppressFinalize
假设如下:
- 一个类只管理成员。
- 一些成员实施
IDisposable
。 - 该类是
sealed
- 一个类不能从非托管资源派生和添加。 - 该对象在
using
语句中使用 - 即Dispose()
在完成时调用。
这个类有 3 种可能的实现IDisposable
:
Dispose
调用成员Dispose()
的最小方法 -没有终结器。IDisposable
IDisposable
带有终结器的标准实现,但缺少GC.SuppressFinalize(this)
.Dispose()
IDisposable
带有终结器(和GC.SuppressFinalize(this)
调用)的完整标准实现Dispose()
。
以下陈述是否正确?我是否正确理解了这一点?
- 情况 A. 的开销比 B. 和 C. 略少,因为对象没有终结器,因此它不会进入 GC 终结队列 - 因为 GC 可以在收集的早期清理这个对象 - 没有开销。
- 情况 B. 对象有一个终结器,因此最终会出现在 GC 终结器队列中,并且终结器将被调用(因为它没有被抑制) - 终结器调用 dispose,因为它已经被调用,所以它什么都不做。这会导致对象在终结器队列中的小开销和终结器调用的非常小的开销。
- 案例 C. 对象有一个终结器,因此仍会在 GC 终结器队列中结束。因为 dispose 并因此
SuppressFinalize
被称为终结器将不会运行。这种情况仍然会导致进入终结器队列的对象的开销很小,但终结器实际上并没有运行。
这里的关键点是很容易认为“我通过调用避免了终结器开销SuppressFinalize
” - 但我认为(并且想澄清)这是不正确的。仍在终结器队列中的对象的开销仍然存在 - 您所避免的只是实际的终结器调用 - 在常见情况下只是“我已经被处置已经什么都不做”。
注意:这里的“完全标准IDisposable
实现”是指旨在涵盖非托管和托管资源情况的标准实现(注意这里我们只有托管对象成员)。
c# - 请问 GC.SuppressFinalize 有什么实质性影响吗?
是的,我知道如何使用GC.SuppressFinalize()
-这里有解释。我读过很多次使用GC.SuppressFinalize()
从终结队列中删除对象,并且认为这很好,因为它使 GC 从调用终结器的额外工作中解脱出来。
所以我制作了这个(主要是无用的)代码,类IDisposable
在链接到答案中实现:
这里我Sleep(0)
用来模仿一些简短的非托管工作。请注意,由于类中的布尔字段,此非托管工作永远不会执行超过一次 - 即使我Dispose()
多次调用或者如果对象首先被释放然后完成 - 在任何这些情况下,“非托管工作”只执行一次.
这是我用于测量的代码:
是的,我将刚刚处理的对象添加到List
.
所以我运行上面的代码,它在 12.01 秒内运行(发布,没有调试器)。然后我注释掉GC.SuppressFinalize()
调用并再次运行代码,它在 13.99 秒内运行。
调用的代码GC.SuppressFinalize()
快了 14.1%。即使在这种荒谬的情况下,所有事情都是为了给 GC 施加压力(你很少用终结器连续制作一千万个对象,不是吗?)差异大约是 14%。
我猜在现实场景中,只有一小部分对象首先具有终结器,并且这些对象也没有大量创建,因此整体系统性能的差异可以忽略不计。
我错过了什么吗?是否有一个现实的场景,我会看到使用 的显着好处GC.SuppressFinalize()
?
c# - 当只有 _unmanaged_ 资源在起作用时,C# Disposable Pattern 可以简化吗?
(注意:这个问题与Calling GC.SuppressFinalize() from inside a finalizer有关,但不是重复的,因为这个问题明确地专门针对no managed resources的情况,而这个问题明确地涉及同时拥有托管和非托管资源的情况资源。)
C# 中经典的一次性模式大致如下:
基本原理是,当一个实例MyClass
被显式处理时(通过调用Dispose()
方法——可能但不一定,通过使用using
),那么我们想要释放所有资源,无论是托管还是非托管,而当实例被垃圾收集而没有已经被处理掉了,那么我们只想释放非托管资源,将托管资源留给其他地方处理(例如,让它们一直存在,直到它们本身也被垃圾收集)。
顺便说一句,注意 call GC.SuppressFinalize(this)
,它告诉垃圾收集器如果实例被垃圾收集,则不需要调用终结器,因为Dispose()
已经调用并负责释放资源。由于使用了该alreadyDisposed
标志,因此如果确实调用了终结器,则没有真正的危险,但这是不必要的,并且让垃圾收集器知道这允许它跳过将实例放入终结队列中,从而可能释放它(以及它的其他东西)参考)更快。
但是现在我们只有非托管资源的情况呢?我希望找到以下更简单的模式:
再次注意 call GC.SuppressFinalize(this)
,它具有与上面相同的功能。在这种情况下,它可能最终会被终结器本身(间接)调用,但据我所知,这并没有什么坏处。
这种一次性模式的形式看起来更简单,而且据我所知,在不涉及托管资源的情况下完全足够了。然而,我还没有在任何地方看到它,或者至少我没有看到它在任何地方被宽恕。
这种模式是否有意义,还是存在根本缺陷?
c# - 为什么我们仍然可以使用已处置的对象?
我有从 IDisposable 继承的 DisposedPatterenDemo 类。我已经处理了这个类的对象,然后在它尝试调用同一个类的 Method() 之后,我从 Method 获取返回值,但 obj 已经被处理掉了。var res=obj.Method(); 没有失败?为什么它没有失败?
c# - 如果对象没有终结器,GC.SuppressFinalize() 是否有效?
我知道,由于某些版本StreamWriter
停止支持终结器,但在源代码中我看到它调用GC.SuppressFinalize(this)
. 为什么叫它?我认为它实际上仅适用于具有终结器的对象。
更新
我想知道GC.SuppressFinalize()
如果对象没有终结器是否有一些影响?