网上演练
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.

72 lines
2.1 KiB

// Needed for NET40
#if !NET_4_6
using System;
using LinqInternal.Threading;
namespace LinqInternal.Collections.ThreadSafe
{
internal class Pool<T>
where T : class
{
private readonly RuntimeUniqueIdProdiver.UniqueId _id;
private readonly FixedSizeQueue<T> _entries;
private readonly Action<T> _recycler;
public Pool(int capacity)
{
_id = RuntimeUniqueIdProdiver.GetNextId();
_entries = new FixedSizeQueue<T>(capacity);
_recycler = GC.KeepAlive;
}
public Pool(int capacity, Action<T> recycler)
{
if (recycler == null)
{
throw new ArgumentNullException("recycler");
}
_id = RuntimeUniqueIdProdiver.GetNextId();
_entries = new FixedSizeQueue<T>(capacity);
_recycler = recycler;
}
internal bool Donate(T entry)
{
// Assume anything could have been set to null, start no sync operation, this could be running during DomainUnload
if (entry != null && ReentryGuardHelper.Enter(_id))
{
try
{
var entries = _entries;
var recycler = _recycler;
if (entries != null && recycler != null)
{
recycler.Invoke(entry);
entries.Add(entry);
return true;
}
return false;
}
catch (InvalidOperationException exception)
{
GC.KeepAlive(exception);
}
catch (NullReferenceException exception)
{
GC.KeepAlive(exception);
}
finally
{
ReentryGuardHelper.Leave(_id);
}
}
return false;
}
internal bool TryGet(out T result)
{
return _entries.TryTake(out result);
}
}
}
#endif