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

107 lines
2.9 KiB

// Needed for Workaround
#if !NET_4_6
using System;
using System.Reflection;
using LinqInternal.Threading;
using LinqInternal.Threading.Needles;
namespace LinqInternal.Collections.ThreadSafe
{
[System.Diagnostics.DebuggerNonUserCode]
internal sealed class WeakDelegateCollection : WeakCollection<Delegate, WeakDelegateNeedle>
{
private readonly Action<object[]> _invoke;
public WeakDelegateCollection()
{
_invoke = InvokeExtracted;
}
public WeakDelegateCollection(bool autoRemoveDeadItems, bool reentryGuard)
: base(autoRemoveDeadItems)
{
if (reentryGuard)
{
_invoke = InvokeExtracted;
}
else
{
var guard = new ReentryGuard();
_invoke = input => guard.Execute(() => InvokeExtracted(input));
}
}
public WeakDelegateCollection(bool autoRemoveDeadItems, bool reentryGuard, int maxProbing)
: base(autoRemoveDeadItems, maxProbing)
{
if (reentryGuard)
{
_invoke = InvokeExtracted;
}
else
{
var guard = new ReentryGuard();
_invoke = input => guard.Execute(() => InvokeExtracted(input));
}
}
public WeakDelegateCollection(int maxProbing)
: base(maxProbing)
{
_invoke = InvokeExtracted;
}
public void Add(MethodInfo method, object target)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
Add(new WeakDelegateNeedle(method, target)); // Since it is a new object, it should not fail
}
public bool Contains(MethodInfo method, object target)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
return Contains(item => item.Equals(method, target));
}
public void Invoke(params object[] args)
{
_invoke(args);
}
public bool Remove(MethodInfo method, object target)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
foreach (var item in RemoveWhereEnumerable(item => item.Equals(method, target)))
{
GC.KeepAlive(item);
return true;
}
return false;
}
private void InvokeExtracted(object[] args)
{
foreach (var handler in GetNeedleEnumerable())
{
try
{
handler.TryInvoke(args);
}
catch (NullReferenceException)
{
// Empty
}
}
}
}
}
#endif