##// END OF EJS Templates
Added 'Fail' method to RunnableComponent which allows component to move from...
Added 'Fail' method to RunnableComponent which allows component to move from Running to Failed state. Added PollingComponent a timer based runnable component More tests Added FailPromise a thin class to wrap exceptions Fixed error handling in SuccessPromise classes.

File last commit:

r152:240aa6994018 v2
r203:4d9830a9bbb8 v2
Show More
Disposable.cs
102 lines | 4.2 KiB | text/x-csharp | CSharpLexer
using Implab.Diagnostics;
using System;
using System.Threading;
namespace Implab.Components {
/// <summary>
/// Base class the objects which support disposing.
/// </summary>
public class Disposable : IDisposable {
int m_disposed;
public event EventHandler Disposed;
public bool IsDisposed {
get {
Thread.MemoryBarrier();
return m_disposed != 0;
}
}
/// <summary>
/// Asserts the object is not disposed.
/// </summary>
/// <exception cref="ObjectDisposedException">The object is disposed</exception>
/// <remarks>
/// Успешная проверка того, что объект не освобожден еще не гарантирует, что он не
/// будет освобожден сразу после нее, поэтому методы использующие проверку должны
/// учитывать, что объект может быть освобожден из параллельного потока.
/// Данны метод служит для упрощения отладки ошибок при использовании объекта после его
/// освобождения.
/// </remarks>
/// <example>
/// // пример синхронизированного освобождения ресурсов
/// class FileStore : Disposable {
/// readonly TextWriter m_file;
/// readonly obejct m_sync = new object();
///
/// public FileStore(string file) {
/// m_file = new TextWriter(File.OpenWrite(file));
/// }
///
/// public void Write(string text) {
/// lock(m_sync) {
/// AssertNotDisposed();
/// m_file.Write(text);
/// }
/// }
///
/// protected override void Dispose(bool disposing) {
/// if (disposing)
/// lock(m_sync) {
/// m_file.Dipose();
/// base.Dispose(true);
/// }
/// else
/// base.Dispose(false);
/// }
/// }
/// <example>
protected void AssertNotDisposed() {
Thread.MemoryBarrier();
if (m_disposed != 0)
throw new ObjectDisposedException(ToString());
}
/// <summary>
/// Вызывает событие <see cref="Disposed"/>
/// </summary>
/// <param name="disposing">Признак того, что нужно освободить ресурсы, иначе данный метод
/// вызван сборщиком мусора и нужно освобождать ТОЛЬКО неуправляемые ресурсы ТОЛЬКО этого
/// объекта.</param>
/// <remarks>
/// Данный метод вызывается гарантированно один раз даже при одновременном вызове <see cref="Dispose()"/>
/// из нескольких потоков.
/// </remarks>
protected virtual void Dispose(bool disposing) {
if (disposing) {
EventHandler temp = Disposed;
if (temp != null)
temp(this, EventArgs.Empty);
}
}
public void Dispose() {
if (Interlocked.Increment(ref m_disposed) == 1) {
Dispose(true);
GC.SuppressFinalize(this);
}
}
/// <summary>
/// Записывает сообщение об утечке объекта.
/// </summary>
protected virtual void ReportObjectLeaks() {
TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
}
~Disposable() {
Dispose(false);
ReportObjectLeaks();
}
}
}