About the collection of unmanaged Resources

Source: Internet
Author: User

There are two ways to release unmanaged Resources

 

1. destructor

2. Implement the system. idisposable Interface

 

I. destructor

The constructor can specify certain operations that must be performed when the class instance is created. When the Garbage Collector deletes an object, it can also call the destructor. At the beginning of the destructor, it seems that it is the best place to place the code for releasing unhosted resources and executing general cleanup operations. However, it is not that simple. The running rules of the garbage collector determine that the code to run at a certain time cannot be placed in the destructor. If the object occupies valuable and important resources, release these resources as quickly as possible, so you cannot wait for the garbage collector to release them.

Instance

C # code Replication
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; 
namespace MemRelease
{    class Program    {        ~Program()        {            // Orders.        }         static void Main(string[] args)        {        }    }} 

 

In Il dasm, you will find that there is no such structure method. C # When the compiler compiles the destructor, it implicitly compiles the Destructor code into the corresponding code of the finalize () method to ensure that the finalize () of the parent class is executed () method:

C # code Replication
.method family hidebysig virtual instance void 
        Finalize() cil managed
{  // Code size       14 (0xe)  .maxstack  1  .try  {    IL_0000:  nop    IL_0001:  nop    IL_0002:  leave.s    IL_000c  }  // end .try  finally  {    IL_0004:  ldarg.0    IL_0005:  call       instance void [mscorlib]System.Object::Finalize()    IL_000a:  nop    IL_000b:  endfinally  }  // end handler  IL_000c:  nop  IL_000d:  ret} // end of method Program::Finalize 

 

Several problems with using destructor to release resources:

 

1. Compared with C ++ destructor, the problem with C # destructor is their uncertainty. When a C ++ object is deleted, its destructor will be executed immediately. However, due to the working method of the garbage collector, it cannot be determined when the destructor of the C # object will be executed.

2. The execution of the C # destructor delays the time when the object is finally deleted from the memory. Objects with destructor need to be processed twice before they can be deleted: objects are not deleted when you call the Destructor for the first time.

 

Ii. idisposable Interface

The idisposable interface defines a pattern that provides a definite mechanism for releasing unhosted resources and avoids problems inherent in the garbage function generator. The idisposable interface declares a method dispose (), which does not contain parameters and returns void.

 

1. msdn recommends implementing the idisposable interface in the following mode.

C # code Replication
 public class Foo: IDisposable
 {     public void Dispose()     {        Dispose(true);        GC.SuppressFinalize(this);     }       protected virtual void Dispose(bool disposing)     {        if (!m_disposed)        {            if (disposing)            {               // Release managed resources            }              // Release unmanaged resources              m_disposed = true;        }     }       ~Foo()     {        Dispose(false);     }       private bool m_disposed; }

 

In the. NET object, there are actually two functions used to release resources: dispose and finalize.

 

(1) Finalize is used to release unmanaged resources, while dispose is used to release all resources, including hosted and unmanaged

 

(2) void dispose (bool disposing) function uses a disposing parameter to identify whether the current call is called by dispose ().

If it is called by dispose (), you need to release both hosted and unmanaged resources. If it is ~ Foo () (that is, the finalize () of C #) is called, you only need to release the unmanaged resources.

 

(3) The dispose () function is explicitly called by other code and requires resource release, while finalize is called by GC.

Other Managed Objects referenced by foo during GC calls may not need to be destroyed, and GC calls the objects even if they are to be destroyed. Therefore, you only need to release unmanaged resources in finalize. On the other hand, 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.

 

However, even if you call finalize and dispose repeatedly, the resource is released only once because of the existence of the variable m_disposed. Excessive calls are ignored.

 

Finalize and dispose are guaranteed.

 

(1) Finalize only releases unmanaged resources;

(2) dispose releases managed and unmanaged resources;

(3) It is no problem to repeatedly call finalize and dispose;

(4) Finalize and dispose share the same resource release policies, so there is no conflict between them.

 

 

 

 

2. idisposable example

 

C # code Replication
Reclaim namespace Resources
{Class program {static void main (string [] ARGs) {// use using to manage resources for Classes implementing idisposable/* when getting an object, first, determine whether the object has implemented the idisposable interface. If yes, it is best to wrap the object with using to ensure that the object is released after it is used up, otherwise, resource leakage may occur. */using (telphone T1 = new telphone () {t1.open (); t1.speak ("hello"); t1.bomb (); // t1.dispose (); // If the dispose () method is called to release resources, an error occurs when the t1.open () method is executed, and the telephone line has been cut off, you cannot call t1.open (); t1.speak ("I am back! ");} // After the code is executed here, the dispose method will be called to recycle resources console. readkey () ;}/// <summary> // The telphone class implements the idisposable interface /// </Summary> class telphone: idisposable {// <summary> // call status /// </Summary> private telphonestate state; /// <summary> /// call /// </Summary> Public void open () {If (State = telphonestate. disposed) {Throw new exception ("the telephone line has been cut off and cannot be opened! ");} State = telphonestate. open; console. writeline ("pick up the phone ");} /// <summary> /// speech /// </Summary> /// <Param name = "S"> speech content </param> Public void speak (string s) {If (State! = Telphonestate. open) {Throw new exception ("no connection");} console. writeline (s) ;}/// <summary> /// call down /// </Summary> Public void bomb () {state = telphonestate. close; console. writeline ("call down") ;}# region idisposable member /// <summary> /// implement dispose () in the idisposable Interface () method To release unmanaged resources // how to release unmanaged resources is determined by the program // </Summary> Public void dispose () {If (State = telphonestate. open) {bomb (); // call down} state = telphonestate. disposed; console. writeline ("Cut off telephone line") ;}# endregion }/// <summary> // call status enumeration /// </Summary> Enum telphonestate {open, close, disposed }}

 

Program running result:

 

 

 

 

Iii. Example of mixed calls of destructor and idisposable

 

C # code Replication
public class ResourceHolder : IDisposable
{Private bool isdispose = false; // display the called dispose method public void dispose () {dispose (true); GC. suppressfinalize (this);} // The actual cleanup method protected virtual void dispose (bool disposing) {If (! Isdisposed) {If (disposing) {// Delete the managed object here .} // here, clear the unmanaged object} isdisposed = true;} // destructor ~ Resourceholder () {dispose (false );}}

About the collection of unmanaged Resources

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.