2011-04-21 40 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 
      } 
     } 
    } 
}