#if NET20 || NET30 || NET35 || !NET_4_6 using System.Collections.Generic; using LinqInternal.Core; using LinqInternal.Threading; namespace System.Threading { [Diagnostics.DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueForDebugDisplay}")] public sealed class ThreadLocal : IDisposable { private int _disposing; private IThreadLocal _wrapped; public ThreadLocal() : this(TypeHelper.GetDefault(), false) { //Empty } public ThreadLocal(bool trackAllValues) : this(TypeHelper.GetDefault(), trackAllValues) { //Empty } public ThreadLocal(Func valueFactory) : this(valueFactory, false) { //Empty } public ThreadLocal(Func valueFactory, bool trackAllValues) { if (valueFactory == null) { throw new ArgumentNullException("valueFactory"); } if (trackAllValues) { _wrapped = new TrackingThreadLocal(valueFactory); } else { _wrapped = new NoTrackingThreadLocal(valueFactory); } } [Diagnostics.DebuggerNonUserCode] ~ThreadLocal() { try { //Empty } finally { Dispose(false); } } public bool IsValueCreated { get { if (Thread.VolatileRead(ref _disposing) == 1) { throw new ObjectDisposedException(GetType().FullName); } else { return _wrapped.IsValueCreated; } } } public T Value { get { if (Thread.VolatileRead(ref _disposing) == 1) { throw new ObjectDisposedException(GetType().FullName); } else { return _wrapped.Value; } } set { if (Thread.VolatileRead(ref _disposing) == 1) { throw new ObjectDisposedException(GetType().FullName); } else { _wrapped.Value = value; } } } public IList Values { get { return _wrapped.Values; } } internal T ValueForDebugDisplay { get { return _wrapped.ValueForDebugDisplay; } } [Diagnostics.DebuggerNonUserCode] public void Dispose() { try { Dispose(true); } finally { GC.SuppressFinalize(this); } } public override string ToString() { return string.Format(Globalization.CultureInfo.InvariantCulture, "[ThreadLocal: IsValueCreated={0}, Value={1}]", IsValueCreated, Value); } [Diagnostics.DebuggerNonUserCode] private void Dispose(bool disposeManagedResources) { if (disposeManagedResources) { if (Interlocked.CompareExchange(ref _disposing, 1, 0) == 0) { _wrapped.Dispose(); _wrapped = null; } } } } } #endif