2012-06-27 3 views
3

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

Мой вопрос: что произойдет, если метод исключает исключение в делегировании многоадресной передачи? Он остановится? Продолжать ? Как обращаться? Небольшая программа с объяснением будет действительно полезна, если кто-то может поделиться с вами .... спасибо ....

ответ

10

Исключение будет немедленно распространено, и любые «более поздние» действия в списке вызовов делегата будут выполнены , а не. Если вы хотите, чтобы вы выполнили все, делегаты, возможно, объединив все исключения вместе, например, вам нужно позвонить Delegate.GetInvocationList, отбросить каждого из этих делегатов того же типа, что и оригинал, и вызвать их одним один, улавливая исключения, когда их бросали.

Вот пример кода, который делает это - было бы неплохо сделать это более общим образом, идеально построив новый делегат, который (при исполнении) выполнил бы все составные делегаты и заполнил бы исключения ... но это начало.

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); 
     } 
    } 
} 
+0

Привет, Джон, спасибо, это именно то, что я пытался понять. Что ж. Одна вещь, которую я не понимаю в вашем заявлении, заключается в следующем: «Передача каждого из этих делегатов одному типу» означает, что вы говорите о нескольких отдельных делегатах? хм, извините, не мог понять это, поскольку я новичок в этом .... Я знаю, что это может быть глупо .... – Learner

+0

@Divine: Каждый из элементов массива, возвращаемых 'GetInvocationList', является тем же типом, что и оригинал делегат - но один с одним действием. Это прекрасно, если вас это смущает - отсутствие хорошей терминологии не помогает :( –

+0

Здесь я думаю, что я немного смущен термином «тип» ... тип относится к типу возврата, о котором вы говорите? Или подписи? знал, что void - это тип возврата для делегатов многоадресной передачи ... и фантастическая программа для меня, чтобы понять ... Я буду использовать это в своем VS и понять это сейчас .... :) Большое вам спасибо, Jon, я ценю это. .. :) – Learner

0

Он будет работать как и любое другое исключение, и он будет работать так же, как делегат не-многоадресной передачи: исключение распространяет стек.

Смежные вопросы