Standard dispose implementation

Source: Internet
Author: User

Original article: http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html

 

C #Program(Or. NET. Simply put, every type in C # represents a resource, and resources are divided into two categories:

Managed resources: Resources allocated and released by CLR management, that is, new objects in CLR;

Unmanaged resources: objects not managed by CLR, Windows kernel objects, such as files, database connections, sockets, and COM objects;

Without exception, if our types Use unmanaged resources, or we need to explicitly release managed resources, we need to let the type inheritance interface idisposable. This is equivalent to telling the caller that this type requires explicit resource release and you need to call my dispose method.

However, this is not so simple. A standard that inherits the type of the idisposable interface should be implemented as follows. This implementation is called the dispose mode:

Public Class Sampleclass: idisposable
{
// Demonstrate creating an unmanaged Resource
Private Intptr nativeresource = Marshal. allochglobal ( 100 );
// Demonstrate creating a Managed Resource
Private Anotherresource managedresource = New Anotherresource ();
Private Bool Disposed = False ;

/// <Summary>
/// Implement the dispose method in idisposable
/// </Summary>
Public Void Dispose ()
{
// Must be true
Dispose ( True );
// Notifies the garbage collection mechanism not to call the terminator (destructor)
GC. suppressfinalize ( This );
}

///


/// not necessary, A close method is provided only to better comply with the standards of other languages (such as C ++)
///
Public void close ()
{< br> dispose ();
}

///<Summary>
///Required, in case that the programmer forgets to explicitly call the dispose method
///</Summary>
~Sampleclass ()
{
//Must be false
Dispose (False);
}

/// <Summary>
/// Protected virtual for non-seal class Modification
/// Private for sealing class Modification
/// </Summary>
/// <Param name = "disposing"> </param>
Protected Virtual Void Dispose ( Bool Disposing)
{
If (Disposed)
{
Return ;
}
If (Disposing)
{
// Clear managed resources
If (Managedresource ! = Null )
{
Managedresource. Dispose ();
Managedresource = Null ;
}
}
// Clear unmanaged Resources
If (Nativeresource ! = Intptr. Zero)
{
Marshal. freehglobal (nativeresource );
Nativeresource = Intptr. zero;
}
// Let the type know that it has been released
Disposed = True ;
}

PublicVoidSamplepublicmethod ()
{
If(Disposed)
{
ThrowNewObjectdisposedexception ("Sampleclass","Sampleclass is disposed");
}
//Omitted
}
}

In the dispose mode, almost every row has a special meaning.

In the standard dispose mode, we noticed ~ Method:

/// <Summary>
/// Required, in case that the programmer forgets to explicitly call the dispose method
/// </Summary>
~ Sampleclass ()
{
// Must be false
Dispose ( False );
}

This method is called the type Terminator. All the significance of providing the Terminator is that we cannot expect callers of the type to actively call the dispose method. Based on the features that the Terminator will be called by the garbage collector, the Terminator is used to remedy the resource release.

A type of dispose method should be allowed to be called multiple times without throwing an exception. For this reason, the type maintains a private Boolean variable disposed:

Private bool disposed = false;

In actual processingCodeThe following judgment statement is added to the cleanup method:

If (Disposed)
{
Return ;
}
// The code for clearing part is omitted, and the disposed value is true at the end of the method.
Disposed = True ;

This means that if the type is cleared once, the cleanup will not proceed.

It should be noted that in the standard dispose mode, the dispose method that implements the idisposable interface is not actually cleaned up, it actually calls the following protected virtual method with a Boolean parameter:

/// <Summary>
/// Protected virtual for non-seal class Modification
/// Private for sealing class Modification
/// </Summary>
/// <Param name = "disposing"> </param>
Protected Virtual Void Dispose ( Bool Disposing)
{
// Code omitted
}

This protected virtual method is provided to consider that this type will be inherited by other classes. If a subclass exists, the subclass may implement its own dispose mode. The protected virtual method is used to remind the subclass to pay attention to the cleanup of the parent class when implementing its own cleanup method. That is, the subclass must call the base. dispose method in its own release method.

Also, we should have noticed that the virtual method that actually writes the resource release code carries a Boolean parameter. This parameter is provided because hosting resources and unmanaged resources must be treated differently when resources are released.

In the no-parameter dispose method for explicitly releasing resources called by the caller, the call parameter is true:

Public Void Dispose ()
{
// Must be true
Dispose ( True );
// Others omitted
}

This indicates that the Code must process both hosted and unmanaged resources at this time.

In the terminator for implicitly clearing resources called by the garbage collector, the call parameter is false:

~ Sampleclass ()
{
// Must be false
Dispose ( False );
}

This indicates that you only need to process unmanaged resources during implicit cleanup.

Why do we treat managed and unmanaged resources differently. Before seriously explaining this issue, we need to first understand: Do managed resources need to be cleared manually? The types in C # can be divided into two categories. One Class inherits the idisposable interface, and the other class does not. The former is called a non-common type, while the latter is called a common type. Because the non-generic type contains unmanaged resources, it must inherit the idisposable interface. However, this type contains the unmanaged resources and is a managed resource. So do managed resources need to be cleaned by hand? The answer to this question is: normal types in managed resources do not need to be cleared manually, rather than normal types. They need to be cleared manually (that is, the dispose method is called ).

The idea of designing the dispose mode is based on: If the caller explicitly calls the dispose method, the type should be released for all its own resources. If the caller forgets to call the dispose method, the type assumes that all of his managed resources (even the non-common types described in the previous section) are handed over to the Garbage Collector for recycling, instead of manual cleanup. After understanding this point, we can understand why the parameter passed in by the virtual method in the dispose method is true, while in the Terminator, the parameter passed in by the virtual method is false.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.