##// END OF EJS Templates
Added ResetState to RunnableComponent to reset in case of failure...
Added ResetState to RunnableComponent to reset in case of failure Added StateChanged event to IRunnable Renamed Promise.SUCCESS -> Promise.Success Added Promise.FromException Renamed Bundle -> PromiseAll in PromiseExtensions

File last commit:

r152:240aa6994018 v2
r205:8200ab154c8a 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();
}
}
}