2012-06-27 24 views
3

我想了解在多播委託中處理異常的最佳方式是什麼?當多播委託中的方法出現異常時會發生什麼

我的問題是,如果一個方法在多播委託執行中拋出異常會發生什麼?它會停止嗎?繼續嗎?如何處理 ?一個有解釋的小程序將非常有用,如果有人可以分享請....謝謝....

回答

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

在這裏我想我有點混淆術語「類型」...類型是指返回類型你談論?或簽名?因爲我知道無效是多播委託....返回類型和奇妙的程序,我瞭解....我將在我的VS中使用它,並瞭解它現在.... :)非常感謝你,喬恩,我很感激。 .. :) – Learner

0

它會像任何其他異常一樣工作,它將與非多播委託相同:異常傳播堆棧。

相關問題