Recovery methods for. NET unmanaged Resources _ Practical Tips

Source: Internet
Author: User

This article is an example of how to recycle. NET unmanaged resources and share them for your reference. The specific analysis is as follows:

There are two ways to release unmanaged resources

1. destructor function

2. Implement System.IDisposable interface

I. Destructors
Constructors can specify certain actions that must be made when an instance of a class is created, or destructors can be called when the garbage collector deletes an object. At the beginning of a destructor, it seems to be the best place to put code that frees unmanaged resources and performs general cleanup operations. But things are not so simple. Because the rules of the garbage collector dictate that the code that needs to run at a certain time cannot be placed in the destructor, if the object occupies valuable and important resources, it should be freed as quickly as possible, and it cannot wait for the garbage collector to release it.
Instance

Copy Code code as follows:
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 method of destructor. When the C # compiler compiles a destructor, it implicitly compiles the destructor's code into the corresponding code for the Finalize () method, ensuring that the Finalize () method of the parent class looks at the compilation of the destructor in this code:

Copy code code as follows:
. Method family Hidebysig Virtual instance void
Finalize () CIL managed
{
Code size (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


There are several issues with using destructors to free resources:

1, the problem of C # destructor is their uncertainty compared with C + + destructor. When you delete a C + + object, its destructor executes immediately, but because of how the garbage collector works, it is not possible to determine when a C # object's destructor executes.
2. The execution of the C # destructor delays The final deletion of the object from memory. Objects with destructors require 2 processing to be deleted: the first time the destructor is invoked, the object is not deleted, and the second call does not actually delete the object.

Second, IDisposable interface

The IDisposable interface defines a pattern, provides a mechanism for freeing unmanaged resources, and avoids the inherent problem of garbage-function-related problems with destructors. The IDisposable interface declares a method Dispose (), which takes no arguments and returns void.

1. MSDN recommends implementing the IDisposable interface according to the following pattern

Copy Code code as follows:
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
}
Release unmanaged
M_disposed = true;
}
}
~foo ()
{
Dispose (FALSE);
}
private bool m_disposed;
}


There are actually two functions for releasing resources in the. NET object: Dispose and Finalize

(1) The purpose of finalize is to release unmanaged resources, and Dispose is used to release all resources, including managed and unmanaged

(2) The void Dispose (bool disposing) function distinguishes whether the current is called by a Dispose () by a disposing argument
If it is called by Dispose (), then both managed and unmanaged resources need to be released at the same time. If it is called by ~foo () (i.e., C # 's Finalize ()), then only the unmanaged resources need to be freed.

(3) The Dispose () function is explicitly invoked by other code and requires the release of resources, and finalize is called by the GC
The other managed objects that Foo referred to at the time of the GC call may not need to be destroyed, and will be invoked by the GC even if it is to be destroyed. Therefore, only unmanaged resources can be freed in finalize. On the other hand, because the managed and unmanaged resources have been freed in Dispose (), it is not necessary to call finalize again when the object is reclaimed by GC, so call Gc.suppressfinalize (this) in Dispose () Avoid duplicate calls to finalize.

However, even if you call finalize and dispose repeatedly, there is no problem, because the existence of variable m_disposed, the resource will only be released once, the redundant call will be ignored.

Finalize, Dispose guaranteed:

(1), finalize only the release of unmanaged resources;
(2) Dispose release of the managed and unmanaged resources;
(3), repeated calls Finalize and dispose is no problem;
(4), Finalize and Dispose share the same resource-release policies, so there is no conflict between them.

2, IDisposable example

Copy Code code as follows:
Namespace Resource Recovery
{
Class Program
{
static void Main (string[] args)
{
Using using to implement IDisposable classes for resource management
/* To get an object, the first to determine whether the object is implemented IDisposable interface, if implemented, it is best to use a using wrapped this object to ensure that the object is released after use, otherwise it is likely that the problem of resource leakage
*/
using (Telphone t1 = new Telphone ())
{
T1. Open ();
T1. Speak ("Hello");
T1. Bomb ();
T1. Dispose (); if the Dispose () method is called here to release the resource, then the T1 is executed. The Open () method makes an error, the phone line has been cut off, no more calls.
T1. Open ();
T1. Speak ("I am back!");
}//code executes here, the Dispose method is invoked for resource reclamation
Console.readkey ();
}
}
<summary>
The Telphone class implements the IDisposable interface
</summary>
Class Telphone:idisposable
{
<summary>
Phone status
</summary>
Private telphonestate State;
<summary>
Call
</summary>
public void Open ()
{
if (state = = telphonestate.disposed)
{
throw new Exception ("The phone line has been cut off and cannot be opened!") ");
}
state = Telphonestate.open;
Console.WriteLine ("Pick Up the phone");
}
<summary>
Speak
</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>
Hang up the phone.
</summary>
public void Bomb ()
{
state = Telphonestate.close;
Console.WriteLine ("Hang Up the phone");
}
IDisposable Members
}
<summary>
Phone Status Enumeration
</summary>
Enum Telphonestate
{
Open, close, disposed
}
}


The results of the program run as shown in the following illustration:



Example of a hybrid invocation of destructors and IDisposable

Copy Code code as follows:
public class Resourceholder:idisposable
{
private bool Isdispose = false;
Show 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)
{
This performs an operation to clear the managed object.
}
This performs an operation to clear an unmanaged object
}
Isdisposed=true;
}
destructor
~resourceholder ()
{
Dispose (FALSE);
}
}

I hope this article will help you with the ASP.net program design.

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.