. Net object destruction (idisposable and using)

Source: Internet
Author: User

CLR has a garbage collection GC mechanism to manage memory allocation and collection. In most cases,ProgramThe worker only needs to create a new object and will destroy the work of this object.

It is completely handed over to CLR for labor.

However, the classes we write use unmanaged resources, such as file handles, mutex objects used for thread synchronization, or database connections, these resources should follow the principle of "On-demand creation and destruction,

This means that these objects are created only when necessary and destroyed immediately after they are used up.

Destructor is opposite to constructor. when an object is out of its scope (for example, the function where the object is located has been called), the system automatically executes the destructor. Destructor are often used to clean up the aftermath (for example, a piece of memory space is opened up with new when an object is created, and should be released with Delete in the Destructor before exiting ).

Take the C ++ language as an example. The Destructor name should also be the same as the class name, but a Tilde is added before the function name ~, Example ~ Stud () to distinguish it from the constructor. It does not contain any parameters or return values (including void type ). You can only have one destructor and cannot overload it. If you have not compiled the destructor, the compilation system will automatically generate a default destructor without any operation. Therefore, explicit destructor are not used in many simple classes.

Deconstruct

We know that the 'deconstruct 'is used to clear examples of classes. When we use the deconstruct in C #, we must remember the following points:

A class can have only one deconstruct.
The deconstruct cannot be inherited or overloaded.
The deconstruct cannot be called. They are automatically called by the compiler.
The parser cannot contain modifiers or parameters.
The following is a declaration of the class myclass deconstruct:

~ Class ()
{
// Cleaning up code goes here
}

Programmers cannot control when the deconstruct will be executed because it is determined by the garbage collector. The garbage collector checks objects that are not used by the application. It considers these conditions to be clear and reclaim their memory. The parser is also called when the program exits. The act behind the execution of the deconstruct is that it implicitly calls the object. Finalize method of the object base class. Therefore, the deconstruct aboveCodeImplicitly converted:

Protected override void finalize ()
{
Try
{
// Cleaning up.
}
Finally
{
Base. Finalize ();
}
}

Now let's look at an example of how the deconstruct is called. We have three classes A, B, and C. B is derived from a and c from B. Each class has its own constructor and deconstruct. In the main function of the app class, we create the C object.

Using system;
Class
{
Public ()
{
Console. writeline ("Creating ");
}
~ A ()
{
Console. writeline ("destroying ");
}
}

Class B:
{
Public B ()
{
Console. writeline ("creating B ");
}
~ B ()
{
Console. writeline ("destroying B ");
}

}
Class C: B
{
Public C ()
{
Console. writeline ("creating C ");
}

~ C ()
{
Console. writeline ("destroying C ");
}
}
Class app
{
Public static void main ()
{
C = new C ();
Console. writeline ("object created ");
Console. writeline ("press enter to destroy it ");
Console. Readline ();
C = NULL;
// GC. Collect ();
Console. Read ();
}
}

As we expected, the constructors of the base class will be executed and the program will wait for the user to press 'enter '. When this happens, we set the object of class C to null, but the deconstruct is not executed ..!!?? As we said, programmers cannot control when the deconstruct is executed because it is determined by the garbage collector. However, the deconstruct is called when the program exits. You can check this by redirecting the O/P of the program to a text file. I will output it here. Note that the deconstruct of the base class is called because base. Finalize () is called.

Creating
Creating B
Creating C
Object created
Press enter to destroy it
Destroying C
Destroying B
Destroying

So what should you do if you want to call the deconstruct once you have used the object? There are two methods:

Call the Garbage Collector to clean up.

Implements the idisposable dispose method.

 

Call the Garbage Collector

 

You can force the Garbage Collector to clean up the memory by calling the GC. Collect method, but in most cases, this should avoid performance problems due to it. In the above program, remove the comment at GC. Collect. Compile and run it. Now you can see that the deconstruct is executed on the console.

 

 

With the above analysis, we need to make it clear that when the CLR garbage collection thread wants to recycle an object that defines the destructor, it will automatically call its Finalize method.

The main purpose of destructor is to release unmanaged resources. However, the time when the object's destructor (I .e. the Finalize method) is called is uncontrollable because it calls the CLR garbage collection mechanism.

Responsible. For performance consideration, the CLR garbage collection thread runs only when "it thinks it is appropriate, in this way, it is possible that the unmanaged resources occupied by objects cannot be released.

 

It is best to have a way for programmers to actively release these unmanaged resources in a fully controllable manner. For this reason,. NET provides an idispose interface.

 

Implement the idisposable Interface

The idisposable interface includes only one public method, which is declared as void dispose (). We can implement this method to close or release unmanaged resources, such as files, streams, and handles controlled by class cases that implement this interface. This method is used to release resources of all tasks associated with objects. When this method is implemented, the object must seek to ensure that all the resources associated with the inherited structure are also released (uncertain, cannot be turned out ).

Class myclass: idisposable
{
Public void dispose ()
{
// Implementation
}
}

 

When we implement the idisposable interface, we need rules to ensure that dispose is called properly.

The CLR does not think that the idisposable interface is different from other interfaces, because the CLR garbage collection thread does not actively ask whether the object has implemented the idisposable interface.

And automatically call its dispose method. In addition, many programmers may forget to call the dispose method of the object during development. To avoid resource leakage, let the object's destructor also call the dispose method,

This is double insurance. As shown in the following code:

 

Joint use of the deconstruct and idisposable Interfaces

 

Public class myclass: idisposable
{
Private bool isdisposed = false;
Public void dispose ()
{
Dispose (true );
GC. supressfinalize (this );
}
Protected void dispose (bool diposing)
{
If (! Isdisposed)
{
If (disposing)
{
// Clean up managed resources
}
// Clean up unmanaged Resources
}
Isdisposed = true;
}
~ Myclass ()
{
Dispose (false );
}
}

 

This code framework does not seem easy to understand. First, add a dispose (bool) to the class. This method receives a bool type parameter. When the parameter value is true, you can write necessary code to clear managed resources, such

Call the dispose method of other hosted objects referenced by this object. Regardless of the parameter value, this dispose (bool) method must complete the task of clearing unmanaged resources.

When the user explicitly calls the dispose method of the idisposable interface in the application, This method uses true as the real parameter to call the virtual method dispose (bool) defined above, and notifies the CLR garbage collection thread, do not call the Finalize method of this object.

If the user does not explicitly call the dispose method of the idisposable interface, the CLR garbage collection thread is responsible for calling the Finalize method of the object to clean up resources. Note that the input parameter is false, the Finalize method in China is only responsible for releasing unmanaged resources.

~ Myclass ()

{

Dispose (false );

}

Here, the dispose (bool) is reloaded for cleanup, and all the cleanup code is only written in this method. This method is called by the deconstruct and idisposable. Dispose. We should note that dispose (bool) is not called anywhere except in idisposable. Dispose () and deconstruct.

When a customer calls idisposable. Dispose (), the customer deliberately wants to clear the managed and unmanaged resources and complete the cleaning. One thing you must note is that GC. supressfinalize (this) is called immediately after resources are cleared ). This method notifies the Garbage Collector that the deconstructor does not need to be called because it has been cleared.

Note that in the preceding example, the deconstruct uses the parameter false to call dispose. Here we are confident that the Garbage Collector collects managed resources. We only clean up unmanaged resources.

 

Conclusion

 

However, it takes some time to implement the idisposable interface. What if the customer cannot call them properly? For this reason, C # has a cool solution. 'Using' code block. It looks like this:

Using (myclass objcls = new myclass ())
{

}

When the control is completed from the successful running of the using block to the end or an exception is thrown out, the idispose. Dispose () of myclass will be executed. Remember that the example object must implement the system. idisposable interface. The Using statement defines a range of objects to be cleared.

Note:
Differences between constructor and destructor:
Constructor and destructor are two special member functions described in the class body.
The function of the constructor is to use a given value to initialize an object when creating an object.
The Destructor is used to release an object. Before deleting an object, use it for cleanup, which is opposite to the function of the constructor.

 

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.