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
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 |