Как обработать исключение в многоадресном делегате в C#?

Мне дали код, который я вызываю через многоадресный делегат.

Я хотел бы знать, как я могу догнать и обработать любое возникшее там исключение, которое пока не удалось. Я не могу изменить данный код.

Я искал вокруг и обнаружил необходимость вызова GetInvocationList(), но не совсем уверен, полезно ли это.

3 ответа

Решение

Рассмотрим код, используя GetInvocationList:

foreach (var handler in theEvent.GetInvocationList().Cast<TheEventHandler>()) {
   // handler is then of the TheEventHandler type
   try {
      handler(sender, ...);
   } catch (Exception ex) {
      // uck
   }
}   

Это мой старый подход, более новый подход, который я предпочитаю выше, потому что он делает вызов проще, включая использование параметров out/ref (при желании).

foreach (var singleDelegate in theEvent.GetInvocationList()) {
   try {
      singleDelgate.DynamicInvoke(new object[] { sender, eventArg });
   } catch (Exception ex) {
      // uck
   }
}

который индивидуально вызывает каждого делегата, который был бы вызван с

 theEvent.Invoke(sender, eventArg)

Удачного кодирования.


Не забывайте делать стандартную проверку на нуль-защиту (и, возможно, блокировку) при работе с событиями.

Вы можете пройтись по всем делегатам, зарегистрированным в многоадресном списке, и вызывать каждого из них по очереди, оборачивая каждый вызов в блок try - catch.

В противном случае вызовы последующих делегатов в многоадресной рассылке после делегата с исключением будут прерваны.

Поднятый ответ для событий, для делегатов специально попробуйте этот метод расширения:

    public static class DelegateExtensions
{
    public static void SafeInvoke(this Delegate del,params object[] args)
    {
        foreach (var handler in del.GetInvocationList())
        {
            try
            {
                    handler.Method.Invoke(handler.Target, args);
            }
            catch (Exception ex)
            {
                // ignored
            }
        }
    }
}
Другие вопросы по тегам