The
using
keyword can be used as a:
·
Directive,
when it is used to create an alias for a namespace or to import types defined
in other namespaces.
·
Statement,
when it defines a scope at the end of which an object will be disposed.
"using" as statement Provides a convenient syntax
that ensures the correct use of IDisposable objects, which provides a mechanism for releasing unmanaged
resources. IDisposable interface implements Dispose method to explicitly
release unmanaged resources in conjunction with the garbage collector. The
consumer of an object can call this method when the object is no longer needed.
The using statement ensures that Dispose is called
even if an exception occurs while you are calling methods on the object.
NOTE: - The garbage collector
automatically releases the memory allocated to a managed object when that
object is no longer used. However, it is not possible to predict when garbage
collection will occur. Furthermore, the garbage collector has no knowledge of
unmanaged resources such as window handles, or open files and streams.
IDisposable
Interface
Using block can only be used for
the classes that implement the IDisposable interface. In other cases you need
to implement IDisposable then you can call the IDisposable.Dispose
implementation from the finally block of a try/catch statement.
Following code shows implementation of IDisposable
interface.
using System;
using System.ComponentModel;
public class DisposeExample
{
// Create a base class
that implements IDisposable.
public class DerivedClass : IDisposable
{
//
Pointer to an external unmanaged resource.
private IntPtr handle;
//
Other managed resource this class uses.
private Component component =
new Component();
//
Track whether Dispose has been called.
private bool disposed = false;
//
The class constructor.
public DerivedClass(IntPtr handle)
{
this.handle = handle;
}
//
Implement IDisposable.
//
Do not make this method virtual, Derived class should not be able to override
this method.
public void Dispose()
{
Dispose(true);
//
This object will be cleaned up by the Dispose method.
//
Therefore, you should call GC.
//
SupressFinalize to take this object off the finalization queue and prevent
finalization code for this object from executing a second time.
GC.SuppressFinalize(this);
}
//
Dispose(bool disposing) executes in two distinct scenarios.
protected virtual void Dispose(bool disposing)
{
//
Check to see if Dispose has already been called.
if (!this.disposed)
{
// If disposing equals true, dispose
all managed
// and unmanaged resources.
if (disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to
clean up unmanaged resources here.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
//
Use interop to call the method necessary to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
//
Use C# destructor syntax for finalization code.
//
This destructor will run only if the Dispose method does not get called.
//
It gives your base class the opportunity to finalize.
//
Do not provide destructors in types derived from this class.
~DerivedClass()
{
//
Do not re-create Dispose clean-up code here.
//
Calling Dispose(false) is optimal in terms of
//
readability and maintainability.
Dispose(false);
}
}
public static void Main()
{
//
Insert code here to create
//
and use the DerivedClass object.
}
}
Comments
Post a Comment