using Implab.Diagnostics; using System; using System.Diagnostics.CodeAnalysis; using System.Threading; namespace Implab.Components { /// /// Base class the objects which support disposing. /// public class Disposable : IDisposable { public event EventHandler Disposed; public bool IsDisposed { get; private set; } /// /// Asserts the object is not disposed. /// /// The object is disposed /// protected void AssertNotDisposed() { if (IsDisposed) throw new ObjectDisposedException(ToString()); } /// /// Вызывает событие /// /// Признак того, что нужно освободить ресурсы, иначе данный метод /// вызван сборщиком мусора и нужно освобождать ТОЛЬКО неуправляемые ресурсы ТОЛЬКО этого /// объекта. /// /// Данный метод вызывается гарантированно один раз даже при одновременном вызове /// из нескольких потоков. /// protected virtual void Dispose(bool disposing) { if (disposing) Disposed.DispatchEvent(this, EventArgs.Empty); } [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Dipose(bool) and GC.SuppessFinalize are called")] public void Dispose() { if(!IsDisposed) { IsDisposed = true; Dispose(true); GC.SuppressFinalize(this); } } /// /// Записывает сообщение об утечке объекта. /// protected virtual void ReportObjectLeaks() { TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this); } ~Disposable() { Dispose(false); ReportObjectLeaks(); } } }