Tag: 终结器

为什么WeakReference.IsAlive变得虚假?

作为这个问题的后续,我有以下代码: using System; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { class Child { public override string ToString() { return “I am a child!”; } ~Child() { Console.WriteLine(“~Child called”); } } class Test { readonly object _child; readonly WeakReference _ref; readonly GCHandle _gch; // GCHandle is a value type, so it’s safe public Test() { […]

如何确保winform被垃圾收集?

正如我从在线和我的个人实验中学到的那样,表单(System.Windows.Forms.Form)的终结器永远不会被GC调用。 据说在Form GC.SuppressFinalize()的Dispose()内部被调用,因此不会再次调用终结器。 Exapmle: public partial class UpdateForm : Form { public UpdateForm() { InitializeComponent(); // Listen to the event of some model Database.OnDataUpdated += new EventHandler(DataBase_OnDataUpdated); } ~UpdateForm() { // Never gets called. } private void DataBase_OnDataUpdated(object sender, EventArgs e) { // Update data on this form } } 但是,如上面的示例所示,如果表单连接(+ =)某个模型的事件并且不断开( – =)Dispose()中的事件,则表单永远不会被垃圾回收,即使Dispose(被叫。 我要做的是检查表单是否真的是垃圾收集的是我在表单中创建一个大数组以消耗大量内存,如下所示: […]

使用CodeDom终结器?

是否可以将Finalizer添加到CodeDom生成的类中(除了使用CodeSnippetTypeMember)? 我在MSDN上找不到任何关于它的信息。

为什么终结器中的AppDomain.Unload()错误?

这是一些示例代码: using System; namespace UnloadFromFinalizer { class Program { static void Main(string[] args) { Program p = new Program(); } AppDomain domain; Program() { this.domain = AppDomain.CreateDomain(“MyDomain”); } ~Program() { AppDomain.Unload(this.domain);//<– Exception thrown here } } } 我有一个类,它在构造函数中创建一个AppDomain,用于在对象的生命周期内使用。 我想正确清理AppDomain,所以我想我会在终结器中调用Unload。 不幸的是,这会导致抛出CannotUnloadAppDomainException。 AppDomain.Unload的MSDN文档说明: 在某些情况下,如果在终结器中调用,则调用Unload会导致立即的CannotUnloadAppDomainException。 为什么是这样? 是否已清除成员变量“domain”? 该清理是否自动包括卸载AppDomain,还是以某种无法访问的方式存在? 有什么我应该做的,或者我可以安全地转储终结器? (只要在此过程中完全清理了GC,我就不在乎GC何时清除了我的对象。)

为什么SHA1.ComputeHash在很multithreading的高负载下失败?

我看到我维护的一些代码存在问题。 下面的代码有一个private static SHA1成员(这是一个IDisposable但因为它是static ,它永远不应该最终确定)。 但是,在压力下,此代码会抛出一个exception,表明它已被关闭: Caught exception. Safe handle has been closed” Stack trace: Call stack where exception was thrown at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) at System.Security.Cryptography.Utils.HashData(SafeHashHandle hHash, Byte[] data, Int32 cbData, Int32 ibStart, Int32 cbSize) at System.Security.Cryptography.Utils.HashData(SafeHashHandle hHash, Byte[] data, Int32 ibStart, Int32 cbSize) at System.Security.Cryptography.HashAlgorithm.ComputeHash(Byte[] buffer) 有问题的代码是: internal class TokenCache { private static SHA1 […]

如何对终结器进行unit testing?

我有以下类,它是IDisposable对象的装饰器(我省略了它添加的东西),它本身使用一个通用模式实现IDisposable : public class DisposableDecorator : IDisposable { private readonly IDisposable _innerDisposable; public DisposableDecorator(IDisposable innerDisposable) { _innerDisposable = innerDisposable; } #region IDisposable Members public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion ~DisposableDecorator() { Dispose(false); } protected virtual void Dispose(bool disposing) { if (disposing) _innerDisposable.Dispose(); } } 我可以轻松测试调用Dispose()时是否Dispose()了innerDisposable : [Test] public void Dispose__DisposesInnerDisposable() { var mockInnerDisposable […]

为什么总是需要在具有IDisposable成员的对象上实现IDisposable?

据我所知,这是一个公认的规则,如果你有一个类A具有IDisposable成员m,A应该实现IDisposable,它应该调用它内部的m.Dispose()。 我找不到令人满意的理由,为什么会这样。 我理解规则如果你有非托管资源,你应该提供一个终结器和IDisposable,这样如果用户没有显式调用Dispose,终结器仍将在GC期间清理。 但是,根据该规则,您似乎不需要具有此问题的规则。 例如… 如果我有课: class MyImage{ private Image _img; … } 约定规定我应该有MyImage : IDisposable 。 但是如果Image遵循惯例并实现了终结器而我不关心资源的及时发布,那有什么意义呢? UPDATE 我在这里找到了一个很好的讨论。

是不是保证完成运行的析构函数?

析构函数很奇怪 。 我试图通过使用“智能”参考管理来消除使用一次性模式的需要,确保垃圾收集器可以在正确的时间收集对象。 在我的一个析构函数中,我不得不等待来自另一个对象的事件,我注意到它没有。 应用程序只是关闭,析构函数在执行过程中终止。 我希望总是允许析构函数完成运行,但是下面的测试表明这不是真的。 using System; using System.Diagnostics; using System.Threading; namespace DestructorTest { class Program { static void Main( string[] args ) { new DestructorTest(); new LoopDestructorTest(); using ( new DisposableTest() ) { } } } class DestructorTest { ~DestructorTest() { // This isn’t allowed to finish. Thread.Sleep( 10000 ); } } class […]

尽管仍然强烈引用,C#WeakReference对象在终结器中为NULL

嗨,我在这里有代码,我不明白为什么我会遇到断点(见评论)。 这是微软的一些我不知道或我不理解的错误吗? 代码在Debug中测试过,但我认为它不会改变任何东西。 注意:您可以直接在控制台应用程序中测试代码。 只是为了信息…在超级猫的回答之后,我用提出的解决方案修复了我的代码并且它工作得很好:-) !!! 糟糕的是静态字典的使用和它的性能,但它的工作原理。 ……几分钟后,我意识到SuperCat给了我更好的提示,解决静态字典并且我做了。 代码示例如下: 代码有bug 代码已更正但具有静态ConditionalWeakTable 包含SuperCat技巧的ConditioalWeakTable代码(非常感谢他!) 样本… using System; using System.Collections.Generic; using System.Diagnostics; namespace WeakrefBug { // ********************************************************************** class B : IDisposable { public static List AllBs = new List(); public B() { AllBs.Add(this); } private bool disposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual […]

当我们没有析构函数时,为什么要调用SuppressFinalize

我有几个问题,我无法得到正确的答案。 1)当我们没有析构函数时,为什么我们应该在Dispose函数中调用SuppressFinalize。 2)Dispose和finalize用于在对象被垃圾收集之前释放资源。 无论是托管资源还是非托管资源我们都需要释放它,那么为什么我们需要在dispose函数中使用一个条件,当我们从IDisposable调用这个重写函数时传递’true’:从finalize调用时Dispose并传递false。 请参阅我从网上复制的以下代码。 class Test : IDisposable { private bool isDisposed = false; ~Test() { Dispose(false); } protected void Dispose(bool disposing) { if (disposing) { // Code to dispose the managed resources of the class } // Code to dispose the un-managed resources of the class isDisposed = true; } public void Dispose() […]