2011-07-11 44 views
2

我有一個類可以觸發事件委託給編組爲DispatcherObject的目標,但是我遇到問題,如果處理程序在它的事件代碼中引發異常,我應該怎麼做?我不想阻止其他聽衆處理該事件。我正在尋找如何處理這樣的問題的建議。關於處理多線程事件中的異常的建議

給出一個抽象基類與Saved事件,我的模式是如下:

public event EventHandler<EventArgs> Saved; 
public void Save() { 
    try { 
     OnSave(); 
    } catch (Exception) { 
     // What should I do here? throwing prevents subsequent handlers, 
     // while catching gobbles up the exception. Should this be in OnSave()? 
    } 
} 
protected virtual void OnSave() { 
    EventHandler<EventArgs> evt = Saved; 
    if (evt != null) { 
     var args = EventArgs.Empty; 
     foreach (var handler in evt.GetInvocationList()) { 
      var target = handler.Target as DispatcherObject; 
      if (target == null || target.CheckAccess()) { 
       var h = handler as EventHandler<EventArgs>; 
       if (h != null) h(this, args); 
      } else { 
       target.Dispatcher.Invoke(handler, this, args); 
      } 
     } 
    } 
} 

我想過建設一個擁有像ArrayException什麼的所有異常的異常,但是這並未」 t看起來沒錯。

建議在這裏做什麼將非常感激。

更新:我感謝丹尼爾和亨裏克你的答案,如果我可以將兩者都標記爲答案,我會決定處理這個事件,因爲我真的不希望它完全被忽視,我的最終解決方案如下(用於尋找解決方案的其他人)。

public event EventHandler<EventArgs> Saved; 
public void Save() { 
    OnSave(); 
} 
protected virtual void OnSave() { 
    EventHandler<EventArgs> evt = Saved; 
    if (evt != null) { 
     var args = EventArgs.Empty; 
     var handlers = evt.GetInvocationList(); 
     var exceptions = new Queue<Exception>(handlers.Length); 
     foreach (var handler in handlers) { 
      try { 
       var target = handler.Target as DispatcherObject; 
       if (target == null || target.CheckAccess()) { 
        var h = handler as EventHandler<EventArgs>; 
        if (h != null) h(this, args); 
       } else { 
        target.Dispatcher.Invoke(handler, this, args); 
       } 
      } catch (Exception ex) { 
       exceptions.Enqueue(ex); 
      } 
     } 
     if (exceptions.Count == 1) { 
      var ex = exceptions.Peek(); 
      throw new Exception(ex.Message, ex); 
     } 
     if (exceptions.Count > 0) { 
      throw new AggregateException(exceptions); 
     } 
    } 
} 

回答

2

無需創建您自己的ArrayException。您可以使用System.AggregateException來包裝多個例外。

+0

現在,這是輝煌的,謝謝你。我發現這在.NET 4中是新的。我想我可能會喜歡在我的「On」方法中使用它。 –

1

從你的代碼中,你似乎應該將循環中的調用包裝到try/catch中,並且在那裏吞噬異常。

我不明白OnSave調用者如何從所有事件處理函數中獲得單一異常都能從中受益。既然你有多個事件句柄,並且從你的架構圖來看,似乎每個人都做了一些完全不同的事情(因爲每個事件都必須被調用),異常空間非常不同,因此調用者無論如何都無法處理它。

所以問題可能是:我如何處理更高級別上的多個事件異常?

您可以嘗試糾正並重新運行OnSave?您是否必須省略通話成功?等等...

+0

Thankyou丹尼爾,你是對的,這個異常應該至少在事件內部被吞噬掉,儘管通過'Application.DispatcherUnhandledException'報告異常是很好的,而不是讓它被注意到,這就是爲什麼我也許一個'ArrayException'可以保存可能發生的所有異常,這樣他們就會擁有該網站的每個異常都來自甚至僅用於報告目的。 –

+0

吃個例外,在某處登錄,然後從那裏去... –