When calling a Multicast Delegate one should use GetInvocationList to call one by one the delegate:
public void IterateAll()
{
if( _doExecute != null )
{
foreach( ExecuteCallback doSingleExecute in _doExecute.GetInvocationList() )
{
try
{
doSingleExecute();
}
catch
{
// This delegate threw an exception
}
}
}
}
Is there a way to genericize this so as to go back to one single call by wrapping this iteration so as to hide it and so that one could call only once again the whole multicast delegate ? This would be closer to the intentional level.
You could do something like this:
public static void CallAllAndCatch(this Action self)
{
if (self == null)
return;
foreach (Action i in self.GetInvocationList()) {
try { i(); }
catch { }
}
}
Note that you can use generics if you find yourself doing this a lot with e.g. EventHandler<T>, but you cannot do this generically for any delegate of any type since delegate types cannot be assigned between each other, even if they are compatible, and there is no mechanism when defining a generic method to restrict a specific generic parameter to be a delegate with a specific signature. (I think delegates with identical signatures are considered compatible types starting with .NET 4.)
For the EventHandler<T> approach:
public static void CallAllAndCatch(this EventHandler<T> self, object sender, T args)
where T : EventArgs
{
if (self == null)
return;
foreach (EventHandler<T> i in self.GetInvocationList()) {
try { i(sender, args); }
catch { }
}
}
If you don't mind throwing performance and compile-time type checking down the tube, you can do this, which will work with any delegate type:
public static void CallAllAndCatch(this Delegate self, params object[] args)
where T : EventArgs
{
if (self == null)
return;
foreach (Delegate i in self.GetInvocationList()) {
try { i.DynamicInvoke(args); }
catch (MemberAccessException) { throw; } // A type of something in args isn't compatible with the delegate signature.
catch (TargetException) { throw; } // The delegate itself is invalid.
catch { } // Catch everything else.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With