网上演练
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
3.6 KiB

#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<T> : IDisposable
{
private int _disposing;
private IThreadLocal<T> _wrapped;
public ThreadLocal()
: this(TypeHelper.GetDefault<T>(), false)
{
//Empty
}
public ThreadLocal(bool trackAllValues)
: this(TypeHelper.GetDefault<T>(), trackAllValues)
{
//Empty
}
public ThreadLocal(Func<T> valueFactory)
: this(valueFactory, false)
{
//Empty
}
public ThreadLocal(Func<T> valueFactory, bool trackAllValues)
{
if (valueFactory == null)
{
throw new ArgumentNullException("valueFactory");
}
if (trackAllValues)
{
_wrapped = new TrackingThreadLocal<T>(valueFactory);
}
else
{
_wrapped = new NoTrackingThreadLocal<T>(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<T> 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