2011-04-21 91 views
4

我已经给出了一些我通过多播委托调用的代码。如何在C#中处理多播委托中的异常?

我想知道我该如何赶上并管理那里引发的任何异常,并且目前尚未进行管理。我无法修改给定的代码。

我一直在环顾四周,发现需要调用GetInvocationList(),但不确定这是否有帮助。

+0

你可以发布你试过的代码? – 2011-04-21 07:05:06

+0

[MulticastDelegate和异常处理的可能的重复:是否有可能一般地包装它?](http://stackoverflow.com/questions/4160031/multicastdelegate-and-exception-handling-is-it-possible-to-wrap -it-all-generica) – svick 2012-03-19 02:09:14

回答

4

考虑使用GetInvocationList代码:

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

这是我的老办法,较新的方法,我宁愿是上面,因为它使调用一个单元,包括使用了/ ref参数(如果需要的话)。

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

其单独调用每一个将被调用,有

theEvent.Invoke(sender, eventArg) 

快乐编码代表。


记住在处理事件时要做标准的空防护copy'n'check(也许是锁定)。

+0

使用这种方法时要非常小心:性能明智,这是非常昂贵的。对于一个事件中的10000个事件处理程序,此方法需要20ms,而常规方法需要1ms。对于10000个事件处理程序,使用旧方法需要1900毫秒到6毫秒。 您需要考虑这一点,并决定性能成本是否值得。我决定这不是在我的情况下 – srodriguez 2012-03-20 00:52:56

+0

当被调用的委托正在修改事件(添加/删除委托)时,这在某些情况下无法正常工作!自己还没有找到解决方法,但MulticastDelegate本身是作为一个链表来实现的,这使得它比平面数组更能抵抗动态修改。 – Oliver 2015-02-12 11:06:57

2

您可以遍历在多播列表中注册的所有代理,并依次调用每个代理,同时将每个调用都封装在try-catch块中。

否则,具有例外的委托之后的组播中后续委托的调用将被中止。

+0

这也是我所做的。 – 2011-04-21 07:07:14

+0

谢谢Jaapjan。所以你的意思是说你和这个例子一样:http://stackoverflow.com/questions/4160031/multicastdelegate-and-exception-handling-is-it-possible-to-wrap-it-all-generical – Goul 2011-04-21 07:14:13

+0

这是要点,是的。围绕着这个话题(现在)和你所提到的这个话题展开了各种各样的例子。 – Jaapjan 2011-04-21 07:17:19

0

的upvoted答案是事件,委托专门试试这个扩展方法:

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