LazyAndWeak.cs
44 lines
| 1.2 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r178 | using System; | ||
using System.Threading; | ||||
namespace Implab.Components { | ||||
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 { | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||