TypeDisposeMethod should release all its resources. It should also call its parent typeDisposeMethod to release all resources of the base type. This parent typeDisposeMethod should release all its resources and also call its parent typeDisposeMethod to spread the mode throughout the base type hierarchy. Make sure that resources are always correctly cleared,DisposeThe method should be called for security multiple times without any exception.
DisposeThe method should be called for the objects it handles . If the object is in the terminate queue,GC. suppressfinalizePreventFinalizeMethod is called. Remember to executeFinalizeThe method greatly compromises the performance. If yourDisposeThe method has completed object cleanup, so the garbage collector does not have to call the objectFinalizeMethod.
The following code example illustrates how to implement classes that encapsulate unmanaged resources.DisposeA possible design pattern of the method. Because this mode is implemented in the entire. NET Framework, you may find it very easy to use. However, this is notDisposeThe only possible implementation of the method.
Resource classes are generally derived from complex native classes or APIs and must be customized accordingly. Use this code mode as a starting point for creating a resource class and provide necessary customization based on encapsulated resources. You cannot compile this example or use it directly for applications.
In this example, the base classBaseResource
Implement public information that can be called by class usersDisposeMethod. This method is called again.Virtual Dispose (bool disposing)Method (in Visual BasicVirtual Dispose (disposing as Boolean)). Pass "true" or "false" based on the caller's identity ". Execute the appropriate cleanup code using the virtual dispose method as the object.
Dispose (bool disposing)It is executed in two different ways. If "disposal" is equal to "true", the method has been called directly or indirectly by the user's code, and can handle hosted and unmanaged resources. If "disposal" is equal to "false", the method is called by the Runtime library from the Terminator and can only be used to dispose of unmanaged resources. Because the terminator does not execute in any specific order, other objects should not be referenced when the object is executing its termination code. If an ongoing Terminator references another terminated object, the ongoing Terminator will fail.
TheFinalizeMethod or destructor cannot be calledDisposeTo act as a protection measure.FinalizeMethod call with ParametersDisposeAnd pass "false ". Should not be inFinalizeMethodDisposeClear the code. CallDispose (false)Code readability and maintainability can be optimized.
ClassMyResourceWrapper
Explains how to useDisposeDerived from the class that implements resource management.MyResourceWrapper
RewriteVirtual Dispose (bool disposing)Methods and provides cleanup code for the hosted and unmanaged resources they have created.MyResourceWrapper
It alsoBaseResource
CallDisposeTo ensure that the base class can be properly cleaned. Note that the derived classMyResourceWrapper
No ParametersFinalizeMethod orDisposeMethod, because the two methods are from the base classBaseResource
Inherit them.
Note:In this exampleProtected dispose (bool disposing)The method does not force thread security, because the method cannot be called simultaneously from the user thread and terminator thread. In additionBaseResource
Client applications should be called at the same time without allowing many user threadsProtected dispose (bool disposing)Method. The design principles of applications or class libraries are as follows: an application or class library should allow only one thread to have the lifetime of the resource and call it when the resource is no longer needed.Dispose. Asynchronous thread access during resource disposal may pose security risks depending on different resources. Developers should carefully check their own code to determine the best way to force thread security.
[Visual Basic]' Design pattern for the base class.' By implementing IDisposable, you are announcing that instances' of this type allocate scarce resources.Public Class BaseResource Implements IDisposable ' Pointer to an external unmanaged resource. Private handle As IntPtr ' Other managed resource this class uses. Private Components As Component ' Track whether Dispose has been called. Private disposed As Boolean = False ' Constructor for the BaseResource Object. Public Sub New() ' Insert appropriate constructor code here. End Sub ' Implement IDisposable. ' Do not make this method Overridable. ' A derived class should not be able to override this method. Public Overloads Sub Dispose()Implements IDisposable.Dispose Dispose(true) ' Take yourself off of the finalization queue ' to prevent finalization code for this object ' from executing a second time. GC.SuppressFinalize(Me) End Sub' Dispose(disposing As Boolean) executes in two distinct scenarios.' If disposing is 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 Overloads Overridable Sub Dispose(disposing As Boolean) ' Check to see if Dispose has already been called. If Not (Me.disposed) Then ' If disposing equals true, dispose all managed ' and unmanaged resources. If (disposing) Then ' Dispose managed resources. Components.Dispose() End If ' Release unmanaged resources. If disposing is false, ' only the following code is executed. CloseHandle(handle) handle = IntPtr.Zero ' Note that this is not thread safe. ' Another thread could start disposing the object ' after the managed resources are disposed, ' but before the disposed flag is set to true. ' If thread safety is necessary, it must be ' implemented by the client. End If Me.disposed = trueEnd Sub ' This Finalize method will run only if the ' Dispose method does not get called. ' By default, methods are NotOverridable. ' This prevents a derived class from overriding this method. Protected Overrides Sub Finalize() ' Do not re-create Dispose clean-up code here. ' Calling Dispose(false) is optimal in terms of ' readability and maintainability. Dispose(false) End Sub ' Allow your Dispose method to be called multiple times, ' but throw an exception if the object has been disposed. ' Whenever you do something with this class, ' check to see if it has been disposed. Public Sub DoSomething() If Me.disposed Then Throw New ObjectDisposedException() End if End SubEnd Class' Design pattern for a derived class.' Note that this derived class inherently implements the ' IDisposable interface because it is implemented in the base class.Public Class MyResourceWrapper Inherits BaseResource ' A managed resource that you add in this derived class. private addedManaged As ManagedResource ' A native unmanaged resource that you add in this derived class. private addedNative As NativeResource ' Track whether Dispose has been called. Private disposed As Boolean = False ' Constructor for the MyResourceWrapper object. Public Sub New() MyBase.New() ' Insert appropriate constructor code here for the ' added resources. End Sub Protected Overloads Overrides Sub Dispose(disposing As Boolean) If Not (Me.disposed) Then Try If disposing Then ' Release the managed resources you added in ' this derived class here. addedManaged.Dispose() End If ' Release the native unmanaged resources you added ' in this derived class here. CloseHandle(addedNative) Me.disposed = true Finally ' Call Dispose on your base class. MyBase.Dispose(disposing) End Try End If End SubEnd Class' This derived class does not have a Finalize method' or a Dispose method without parameters because it ' inherits them from the base class.
[C#]// Design pattern for the base class.// By implementing IDisposable, you are announcing that instances// of this type allocate scarce resources.public class BaseResource: IDisposable{ // Pointer to an external unmanaged resource. private IntPtr handle; // Other managed resource this class uses. private Component Components; // Track whether Dispose has been called. private bool disposed = false; // Constructor for the BaseResource object. public BaseResource() { // Insert appropriate constructor code here. } // Implement IDisposable. // Do not make this method virtual. // A derived class should not be able to override this method. public void Dispose() { Dispose(true); // Take yourself off the Finalization queue // to 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. Components.Dispose(); } // Release unmanaged resources. If disposing is false, // only the following code is executed. CloseHandle(handle); handle = IntPtr.Zero; // Note that this is not thread safe. // Another thread could start disposing the object // after the managed resources are disposed, // but before the disposed flag is set to true. // If thread safety is necessary, it must be // implemented by the client. } disposed = true; } // 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. ~BaseResource() { // Do not re-create Dispose clean-up code here. // Calling Dispose(false) is optimal in terms of // readability and maintainability. Dispose(false); } // Allow your Dispose method to be called multiple times, // but throw an exception if the object has been disposed. // Whenever you do something with this class, // check to see if it has been disposed. public void DoSomething() { if(this.disposed) { throw new ObjectDisposedException(); } }}// Design pattern for a derived class.// Note that this derived class inherently implements the // IDisposable interface because it is implemented in the base class.public class MyResourceWrapper: BaseResource{ // A managed resource that you add in this derived class. private ManagedResource addedManaged; // A native unmanaged resource that you add in this derived class. private NativeResource addedNative; private bool disposed = false; // Constructor for this object. public MyResourceWrapper() { // Insert appropriate constructor code here. } protected override void Dispose(bool disposing) { if(!this.disposed) { try { if(disposing) { // Release the managed resources you added in // this derived class here. addedManaged.Dispose(); } // Release the native unmanaged resources you added // in this derived class here. CloseHandle(addedNative); this.disposed = true; } finally { // Call Dispose on your base class. base.Dispose(disposing); } } }}// This derived class does not have a Finalize method// or a Dispose method without parameters because it inherits // them from the base class.
Close Method
For the type, if you callCloseMethod Comparison callDisposeYou can add a publicCloseMethod.CloseMethod call without ParametersDisposeMethod. The following code example illustratesCloseMethod.
[Visual Basic]' Do not make this method Overridable.' A derived class should not be allowed' to override this method.Public Sub Close() ' Calls the Dispose method without parameters. Dispose()End Sub
[C#]// Do not make this method virtual.// A derived class should not be allowed// to override this method.public void Close(){ // Calls the Dispose method without parameters. Dispose();}