C #14 days of advanced programming ---- release of unmanaged resources,

Source: Internet
Author: User

C #14 days of advanced programming ---- release of unmanaged resources,

Release unmanaged Resources

When introducing the release of unmanaged resources, I think it is necessary to first understand what it is called an unmanaged resource. Since there are unmanaged resources, there must be managed resources.

 

 

Managed resources refer. net resources that can be recycled from the palm, mainly refers to the memory resources allocated on the managed stack. the recovery of managed resources does not require manual intervention.. net Runtime Library in the appropriate call to the Garbage Collector for recycling.

 

Unmanaged resources refer. net does not know how to recycle resources. The most common type of unmanaged resources are the objects that encapsulate operating system resources, such as files, windows, network connections, database connections, image brushes, and icons. this type of resource, the garbage collector will call the Object during cleaning. finalize () method. by default, the method is empty. For unmanaged resources, you need to write code to recycle the unmanaged resources in this method so that the garbage collector can correctly recycle the resources.

 

 

In. net, Object. the Finalize () method cannot be overloaded. The Compiler automatically generates an Object based on the class destructor. the Finalize () method. Therefore, for classes that contain unmanaged resources, you can place the code for releasing unmanaged Resources in the destructor.

 

Note: you cannot release managed resources in the destructor. Because the Destructor are called by the garbage collector, it may be before the Destructor is called, the managed resources contained in the class have been recycled, leading to unpredictable structures.

 

 

Originally, in accordance with the above practice, the unmanaged resources can also be recycled by the garbage collector, but the unmanaged resources are generally limited and valuable, the garbage collector is automatically called by CLR (read my previous article without knowing CLR), so that the first-level release of unmanaged resources cannot be guaranteed. Therefore, a Dispose () method is defined, allows users to manually release unmanaged resources. the Dispose () method is used to protect protected and unmanaged resources. After you manually call this method, the garbage collection period does not recycle such instances. the Dispose () method is called by the user. when calling the Dispose () method, the managed and unmanaged resources of the class are certainly not recycled, so the resources of both classes can be recycled at the same time.

 

Microsoft specifically defines an interface for the collection of unmanaged resources: IDisposable, which can only contain one Dispose () method. Any class containing unmanaged resources should inherit this interface.

 

 

In a class that contains unmanaged resources, the standard practices for resource release are as follows:

(1) inherit the IDisposeable interface;

(2) Dispose () method, in which managed and unmanaged resources are released, and the object itself is removed from the garbage collector (the garbage collector does not recycle this resource );

(3) Implement class destructor to release unmanaged Resources

 

 

When used, it is displayed that the Dispose () method can be called to release resources in a timely manner, and the execution of the Finalize () method is removed to Improve the Performance. If no display is displayed, call Dispose () method, the garbage collector can also release unmanaged resources through the destructor. The Garbage Collector itself has the function of recycling managed resources, so as to ensure the normal release of resources, however, the garbage collector recycles these resources, causing the unmanaged resources to be released in time.

 

In.. net should be used as few as possible to release resources. objects without destructor are deleted from the memory during one processing by the spam processor. However, objects with destructor need to be called twice. The first time the Destructor is called, the second time the object is deleted. in addition, the Destructor contains a large amount of resource release code, which reduces the workload of the garbage collector and affects the performance. therefore, it is best to call the Dispose () method to recycle resources in time for objects that contain unmanaged resources, rather than relying on the garbage collector.

 

The above is how many resources are released for classes that contain unmanaged resources in. net. As long as code is written according to the above steps, it is a class of resource security.

Case:

Class MyResourceWrapper: IDisposable

{

Public void Dispose ()

{

Console. WriteLine ("release resources with Dispose ");

Console. Beep ();

}

}

 

Class Program

{

Static void Main (string [] args)

{

MyResourceWrapper mr = new MyResourceWrapper ();

Mr. Dispose ();

}

}

 

 

When we call the Dispose method, we can hear the system beep.

 

Note: releasing resources with multiple Dispose methods is also potentially risky, because the Dispose method needs to be shown by programmers, if the call to Dispose is missing in the Code or an exception occurs before the call to Dispose and no Dispose is specified, some resources may remain in the memory.

 

Therefore, we should use the following method to ensure that the Dispose method can be called:

Static void Main (string [] args)

{

MyResourceWrapper mr = new MyResourceWrapper ();

Try

{

// Do something wiht mr object

}

Finally

{

Mr. Dispose ();

}

}

 

 

However, every time you write Idspose code, it will be very troublesome to use the try block. Fortunately, in C #, We can reuse the using keyword to simplify the call of Dispose.

 

Reuse using keywords

In C #, the using statement provides an efficient way to call the Dispose method of the object. the using statement can be used for any types of IDisposable interfaces. However, for those types that do not implement the IDisposable interface, using the using statement may cause a compilation error.

 

Static void Main (string [] args)

{

Using (MyResourceWrapper mr = new MyResourceWrapper ())

{

// Do something with mr object

}

}

 

At the end of the using block, the Dispose method of the mr instance is automatically called. The using statement not only saves the programmer from entering the code called by Dispose, but also ensures that the Dispose method is called, whether or not the using statement block is successfully executed. in fact, the C # compiler automatically adds a try/finally statement block to the using statement.

 

 

 

. NET provides two ways to release unmanaged resources. One is the Finalize method and the other is the Dispose method.

 

Next let's take a look at the Finalize method.

In. net base class System. the virtual method named Finalize () is defined in the Object. This method does nothing by default. we can rewrite the Finalize method for the custom type and add the necessary unmanaged resource clearing logic to the method. the garbage collector calls the Finalize method of the object to delete this type of objects from the inner. therefore, regardless. net or GC. the Finalize method is always called. in addition, when the AppDomain carrying the application is removed from the memory, the Finalize method is also called.

 

Override Finalize method

Assume that we have a type of unmanaged resources. We need to rewrite the Finalize method to clean up the unmanaged resources. But when we rewrite the Finalize method in the following way, A compilation error occurs:

Class MyResourceWrapper

{

Protected override void Finalize ()

{}

}

 

In fact, when we want to override the Finalize method, C # provides us with (similar to C ++) destructor syntax (C # Terminator) to override this method. C # The Terminator syntax is similar to the constructor syntax. The method name and type name are the same. The difference is that the terminator has ~ Prefix, and cannot use access modifiers. parameters are not accepted and cannot be overloaded. Therefore, a class can only have one Terminator.

 

Class MyResourceWrapper

{

~ MyResourceWrapper ()

{

Console. WriteLine ("release unmanaged resources ");

Console. Beep (); // t play a prompt on the Console player

}

}

 

The reason why C # only supports this method to rewrite the Finalize method is that the C # compiler evades that the Finalize method implicitly adds some necessary basic code. I will not show you the added basic code. It means that the finalize method can always be executed.

 

 

When we execute the following code, we can hear a beep:

MyResourceWrapper mr = new MyResourceWrapper ();

 

 

Working Mechanism of Finalize

His working mechanism is very complicated. If you want to study it in depth, you can check it on the Internet (no one will check it). I just refer to some simple online statements to understand the working mechanism of Finalize.

In fact, the Finalize method is quite resource-consuming, and the function of the Finalize method is to ensure.. net objects can be cleared when garbage collection is performed. If a type that does not use unmanaged resources is created, the implementation of the terminator has no effect, if there is no special need, we should avoid rewriting the Finalize method.

 

 

 

 

Combination of Dispose and Finalize

 

Finalize can be automatically called through garbage collection, and Dispose needs to be called by code display. so, for the sake of security, it is still necessary to implement a terminator for some unmanaged resources (what is a terminator? Let's look at it at the end). That is to say, if we forget to explicitly call Dispose, in this case, garbage collection also calls Finalize to ensure the collection of unmanaged resources.

 

MSND provides a good mode to implement the IDisposable interface to combine Dispose and FInalize. The example is as follows:

Class MyResourceWrapper: IDisposable

{

Private bool IsDisposed = false;

~ MyResourceWrapper ()

{

 

Dispose (false );

 

}

Public void Dispose (bool disposing)

{

If (! This. IsDisposed)

{

If (disposing)

{

// Clear managed resources

}

// Clear unmanaged Resources

}

This. IsDisposed = true;

}

Public void Dispose ()

{

Dispose (true );

// Tell GC not to call the Finalize method

GC. SuppressFinalize (this );

}

}

 

In this mode, the void Dispose (bool disposing) function uses a disposing parameter to identify whether it is called by Dispose. if it is called by Dispose. if it is called by Dispose (), you need to release both managed and unmanaged resources. if it is called by the Terminator, you only need to release the unmanaged resources. when the Dispose () function is explicitly called by other code, the resource should be released as required, and Finalize is called by GC.

 

In addition, because managed and unmanaged resources have been released in Dispose (), it is unnecessary to call Finalize again when the object is recycled by GC. Therefore, in Dispose (). suppressFinalize (this) prevents repeated calls to Finalize. similarly, because the IsDisposed variable exists, the resource will be released only once, and redundant calls will be ignored.

 

This mode has the following advantages:

1. if Dispose () is not explicitly called and managed and unmanaged resources are not released, the Finalize will be executed during garbage collection to release the unmanaged resources, and GC will release the managed resources.

2. if Dispose () is called, the managed and unmanaged resources can be released in time, so the Finalize () will not be executed when the object is reclaimed by garbage collection (), this improves the efficiency of using unmanaged resources and the system performance.





Finalizer is mainly used for unmanaged code cleanup in C #. Net. It usually implements both the Terminator and the Dispose method. In this way, careful users can directly display that calling the Dispose method will improve the performance of garbage collection. Although careless users forget to call the Dispose method, they will not release unmanaged resources. The Code is as follows:

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.