Dispose of C #

Foreword

Speaking Dispose, we first need to understand C # resources

Resource Type

  • Managed resource: the creation and release by the CLR
  • Unmanaged resource: the creation and release of resources not help CLR management. For example, IO, network connections, database connections, and so on. Require developers to manually released.

How to release

Microsoft is calling the library or third-party libraries, the library will provide a general method of release that the agreement is Dispose, you can call.

Why must the Dispose method?

Each library may of course be provided a method of releasing the respective resources, such as close (), close (), release (), clear () and the like.

But in order to unify, Microsoft provides IDispose interfaces, which only declares a void in the Dispose () method. But also provides a syntactic sugar using the release of resources for the realization of a class IDispose interface.

Look at the code:

namespace System
{
    [ComVisible(true)]
    public interface IDisposable
    {
        //执行与释放或重置非托管资源关联的应用程序定义的任务。
        void Dispose();
    }
}

Forget release how to do?

For example, we add a watermark to the picture function, use System.Drwing class library Image object. Write code, we call the Dispose method is neither a manual nor the using syntax. Image object would then have been left in memory of it?
Of course not, Image class destructor, in which a call to Dispose method.

The source code:

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if (this.nativeImage != IntPtr.Zero)
    {
        try
        {
            SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(this, this.nativeImage));
        }
        catch (Exception ex)
        {
            if (ClientUtils.IsSecurityOrCriticalException(ex))
            {
                throw;
            }
        }
        finally
        {
            this.nativeImage = IntPtr.Zero;
        }
    }
}

~Image()
{
    this.Dispose(false);
}

Since the final destructor will free up resources, then we is not no need to manually release it?
We will talk about the destructor

Destructor

When a class instance is recovered GC, a final method call. It constructors contrary, the latter is called when an instance of the class initialization.

It was written like this:

class Car
{
    ~Car()  // finalizer
    {
        // cleanup statements...
    }
}

Implicitly Finalize method calls the base class, so the equivalent following wording:

protected override void Finalize()  
{  
    try  
    {  
        // Cleanup statements...  
    }  
    finally  
    {  
        base.Finalize();  
    }  
}

Finalize does it, with the following restrictions:

  • The exact time when the finalizer executes is undefined.
  • The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other.
  • The thread on which the finalizer runs is unspecified.

(Source: https://docs.microsoft.com/en-us/dotnet/api/system.object.finalize?view=netframework-4.8 )

Finalize operation simple understanding is determined by GC, recovery time is fixed, variable order, variable thread. So destructor calling Dispose just an insurance policy, and not a substitute for manual release resources.

Such as database connection, you open the connection is not released in time, soon unable to connect the new database. At this time, the GC has not been performed may destructor.

Of course, the destructor when GC recovery, but also because the garbage collection mechanism has other performance issues, detailed in the article we are talking about garbage collection in.

(Reference: https://www.viva64.com/en/b/0437/ )

Dispose pattern

So far, we clearly know that for unmanaged use of resources, we must remember to free up resources.

We give people time libraries are provided, but also understand the need to achieve in the end when the IDispose interfaces.

Of course, there is already realized Dispose of the routine, called Dispose pattern, the following are examples:

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;
   // Instantiate a SafeHandle instance.
   SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);
   
   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }
   
   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 
      
      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.
         //
      }
      
      disposed = true;
   }
}

Yo, just above the Image class which is not so write it?
Yes!

Guess you like

Origin www.cnblogs.com/talentzemin/p/10986063.html
Recommended