Proper use of the IDisposable interface

后端 未结 19 3342
情深已故
情深已故 2020-11-21 04:05

I know from reading the Microsoft documentation that the \"primary\" use of the IDisposable interface is to clean up unmanaged resources.

To me, \"unman

19条回答
  •  滥情空心
    2020-11-21 04:51

    Your given code sample is not a good example for IDisposable usage. Dictionary clearing normally shouldn't go to the Dispose method. Dictionary items will be cleared and disposed when it goes out of scope. IDisposable implementation is required to free some memory/handlers that will not release/free even after they out of scope.

    The following example shows a good example for IDisposable pattern with some code and comments.

    public class DisposeExample
    {
        // A base class that implements IDisposable. 
        // By implementing IDisposable, you are announcing that 
        // instances of this type allocate scarce resources. 
        public class MyResource: IDisposable
        {
            // Pointer to an external unmanaged resource. 
            private IntPtr handle;
            // Other managed resource this class uses. 
            private Component component = new Component();
            // Track whether Dispose has been called. 
            private bool disposed = false;
    
            // The class constructor. 
            public MyResource(IntPtr handle)
            {
                this.handle = handle;
            }
    
            // Implement IDisposable. 
            // Do not make this method virtual. 
            // A derived class should not be able to override this method. 
            public void Dispose()
            {
                Dispose(true);
                // This object will be cleaned up by the Dispose method. 
                // Therefore, you should call GC.SupressFinalize to 
                // take this object off the finalization queue 
                // and prevent finalization code for this object 
                // from executing a second time.
                GC.SuppressFinalize(this);
            }
    
            // Dispose(bool disposing) executes in two distinct scenarios. 
            // If disposing equals true, the method has been called directly 
            // or indirectly by a user's code. Managed and unmanaged resources 
            // can be disposed. 
            // If disposing equals false, the method has been called by the 
            // runtime from inside the finalizer and you should not reference 
            // other objects. Only unmanaged resources can be disposed. 
            protected virtual void Dispose(bool disposing)
            {
                // Check to see if Dispose has already been called. 
                if(!this.disposed)
                {
                    // If disposing equals true, dispose all managed 
                    // and unmanaged resources. 
                    if(disposing)
                    {
                        // Dispose managed resources.
                        component.Dispose();
                    }
    
                    // Call the appropriate methods to clean up 
                    // unmanaged resources here. 
                    // If disposing is false, 
                    // only the following code is executed.
                    CloseHandle(handle);
                    handle = IntPtr.Zero;
    
                    // Note disposing has been done.
                    disposed = true;
    
                }
            }
    
            // Use interop to call the method necessary 
            // to clean up the unmanaged resource.
            [System.Runtime.InteropServices.DllImport("Kernel32")]
            private extern static Boolean CloseHandle(IntPtr handle);
    
            // Use C# destructor syntax for finalization code. 
            // This destructor will run only if the Dispose method 
            // does not get called. 
            // It gives your base class the opportunity to finalize. 
            // Do not provide destructors in types derived from this class.
            ~MyResource()
            {
                // Do not re-create Dispose clean-up code here. 
                // Calling Dispose(false) is optimal in terms of 
                // readability and maintainability.
                Dispose(false);
            }
        }
        public static void Main()
        {
            // Insert code here to create 
            // and use the MyResource object.
        }
    }
    

提交回复
热议问题