using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
namespace Sleis.Utility
{
public interface IIsDisposed
{
bool IsDisposed
{
get;
}
}
///
/// Basic functionality for an object implementing IDisposable
///
public abstract class DisposableBase : IDisposable, IIsDisposed
{
private int _disposedCallCount;
///
/// Safely dispose of an object without allowing exceptions to propogate.
///
///
public static void SafeDispose(object inObject)
{
IDisposable disposable = inObject as IDisposable;
if (disposable != null)
{
try
{
disposable.Dispose();
}
catch (Exception)
{
}
}
}
///
/// Safely dispose of an object without allowing exceptions to propogate, and set input
/// reference to null.
///
///
///
public static void SafeDispose(ref T ioObject) where T : class
{
object obj = ioObject;
ioObject = null;
SafeDispose(obj);
}
~DisposableBase()
{
#if DEBUG
if (!IsDisposed)
{
Assembly entryAssembly = null;
try
{
entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly == null)
{
entryAssembly = Assembly.GetExecutingAssembly();
}
}
catch (Exception)
{
}
DebugUtility.CheckDebuggerBreak();
}
#endif // DEBUG
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
///
/// IsDisposed
///
public bool IsDisposed
{
get
{
return (_disposedCallCount < 0);
}
}
///
/// Implement IDisposable.
/// Do not make this method virtual.
/// A derived class should not be able to override this method.
///
public void Dispose()
{
Dispose(true);
// Take yourself off the Finalization queue
// to prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
///
/// Dispose(bool disposing) executes in two distinct scenarios.
/// If disposing equals true, the method has been called directly
/// or indirectly by a user's code. Managed and unmanaged resources
/// can be disposed.
/// If disposing equals false, the method has been called by the
/// runtime from inside the finalizer and you should not reference
/// other objects. Only unmanaged resources can be disposed.
///
///
protected virtual void Dispose(bool inIsDisposing)
{
// Check to see if Dispose has already been called.
if (Interlocked.Decrement(ref _disposedCallCount) == -1)
{
OnDispose(inIsDisposing);
}
}
///
/// This is the method to override in your subclass.
///
protected abstract void OnDispose(bool inIsDisposing);
}
}