I would like to understand whats the best way to handle exceptions in Multicast delegates ?
My question is, what happens if a method throw exception in Multicast delegate execution ? Will it stop ? Continue ? How to handle ? A small program with explanation will be really helpful if somebody can share please.... thank you....
The multicast delegate contains a list of the assigned delegates. When the multicast delegate is called, it invokes the delegates in the list, in order. Only delegates of the same type can be combined. The - operator can be used to remove a component delegate from a multicast delegate.
A Delegate is a Type-Safe Function Pointer. It means the delegate holds the reference of a method or function and when we invoke the delegate, the method it refers to is going to be executed. The delegate signature and the method it points to must have the same signature.
A MulticastDelegate has a linked list of delegates, called an invocation list, consisting of one or more elements. When a multicast delegate is invoked, the delegates in the invocation list are called synchronously in the order in which they appear.
Multicast Delegate instance is created by combining two Delegates and the invocation list is formed by concatenating the invocation list of the two operands of the addition operation. Delegates are invoked in the order they are added.
The exception will be propagated immediately, and any "later" actions in the delegate's invocation list will not get executed. If you want to make sure you execute all the delegates - perhaps aggregating all the exceptions together, for example - you'd need to call Delegate.GetInvocationList
, cast each of those delegates to the same type as the original, and invoke them one by one, catching the exceptions as they were thrown.
Here's some sample code which does this - it would be nice to do this in a more generic way, ideally building a new delegate which (when executed) would execute all of the constituent delegates and aggregate the exceptions... but this is a start.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
public static void Main()
{
Action x = null;
x += () => Console.WriteLine("First");
x += () => { throw new Exception("Bang 1"); };
x += () => { throw new Exception("Bang 2"); };
x += () => Console.WriteLine("Second");
try
{
ExecuteAll<Action>(x, action => action());
}
catch (AggregateException e)
{
Console.WriteLine(e);
}
}
public static void ExecuteAll<T>(Delegate multi, Action<T> invoker)
{
List<Exception> exceptions = new List<Exception>();
foreach (var single in multi.GetInvocationList())
{
try
{
invoker((T)(object)single);
}
catch (Exception e)
{
exceptions.Add(e);
}
}
if (exceptions.Count > 0)
{
throw new AggregateException(exceptions);
}
}
}
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