##// END OF EJS Templates
Added class Trace<T> to manage channels for individual classes, if SomeClass...
Added class Trace<T> to manage channels for individual classes, if SomeClass uses Trace<SomeClass> it sould be marked with TraceSourceAttribute

File last commit:

r182:76e8f2ba12b8 ref20160224
r212:a01d9df88d74 v2
Show More
LazyAndWeak.cs
64 lines | 2.1 KiB | text/x-csharp | CSharpLexer
using System;
using System.Threading;
namespace Implab.Components {
/// <summary>
/// Creates an instace on-demand and allows it to be garbage collected.
/// </summary>
/// <remarks>
/// Usefull when dealing with memory-intensive objects which are frequently used.
/// This class is similar to <see cref="ObjectPool{T}"/> except it is a singleton.
/// </remarks>
public class LazyAndWeak<T> where T : class {
readonly Func<T> m_factory;
readonly object m_lock;
WeakReference m_reference;
public LazyAndWeak(Func<T> factory, bool useLock) {
Safe.ArgumentNotNull(factory, "factory");
m_factory = factory;
m_lock = useLock ? new object() : null;
}
public LazyAndWeak(Func<T> factory) : this(factory, false) {
}
public T Value {
get {
while (true) {
var weak = m_reference;
T value;
if (weak != null) {
value = weak.Target as T;
if (value != null)
return value;
}
if (m_lock == null) {
value = m_factory();
if (Interlocked.CompareExchange(ref m_reference, new WeakReference(value), weak) == weak)
return value;
} else {
lock (m_lock) {
// double check
weak = m_reference;
if (weak != null) {
value = weak.Target as T;
if (value != null)
return value;
}
// we are safe to write
value = m_factory();
m_reference = new WeakReference(value);
return value;
}
}
}
}
}
}
}