Exceptions during Finalize(): what methodology are you using to detect garbage collector-time exceptions?

后端 未结 4 1199
[愿得一人]
[愿得一人] 2020-12-21 12:38

I am developing a pretty extensive system in .NET, which involves a lot of system programming. Most time, I\'m using the IDisposable pattern to handle resource disposal, but

4条回答
  •  [愿得一人]
    2020-12-21 13:38

    I do the following in my classes, so in debug builds, I can try to catch these type of things.

    In debug builds, an assertion is done to ensure the class was explictly disposed. Another assertion is done to make sure the finalizer doesn't throw. In release/production builds, this check is not performed to improved performance.

    C# code

    using System;
    using System.Diagnostics;
    
    namespace ConsoleApplication8
    {
        class Program
        {
            class IReferenceUnmanagedMem : IDisposable
            {
    #if(DEBUG)
                private static readonly string _ctorStackTrace = Environment.StackTrace;
    #endif
    
                public IReferenceUnmanagedMem()
                {
                }
    
                ~IReferenceUnmanagedMem()
                {
    #if(DEBUG)
                    Debug.Fail("Dispose method not called.", _ctorStackTrace);
                    try
                    {
    #endif
                        Dispose(true);
    #if(DEBUG)
                    }
                    catch(Exception e)
                    {
                        Debug.Fail("Dispose method threw exception in finalizer.", e.ToString());
                    }
    #endif
                }
    
                public void Dispose()
                {
                    Dispose(false);
                    GC.SuppressFinalize(this);
                }
    
                protected virtual void Dispose(bool inFinalizer)
                {
                    if(inFinalizer)
                    {
                        throw new Exception("I Know, this is a no-no.");
                    }
                }
            }
    
            public static void Main()
            {
                IDisposable disposable = new IReferenceUnmanagedMem();
                disposable = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }
    }
    

提交回复
热议问题