2016-11-18 75 views
0

我評估Postsharp以在應用程序中部署。 我想通過postsharp處理我的應用程序中的所有未捕獲的異常。通過這種方式,我在OnExceptionAspect的子類中實現了OnException方法。 通過我的測試,所有異常都被捕獲,除了在一種情況下出現一個異常: 當異常拋入backgroundWorker時。在c#中處理異常backgroundWorker

我的課:

public class Test { 
    public void MethodTest() { 

    //... 
    // if I throw an exception here, no problem : postsharp aspect intercept 
    // below, postsharp don't intercept the exception : 
    BackgroundWorker bgw = new BackgroundWorker() ; 
    bgw.DoWork += (object sender2, DoWorkEventArgs e2) => { 
     //... 
     throw new NotImplementedException(); 
    } 
    bgw.RunWorkerAsync(); 
    } 
} 

你可以爲攔截這個異常的建議嗎?

謝謝你的幫助。

+1

嗨,歡迎來到Stack。不是一個可怕的第一個問題,但我已經稍微編輯了你的標題並更改了標誌。你只是想處理由後臺工作者拋出的異常,這本質上是[this](http://stackoverflow.com/questions/20582253/background-worker-exception-handling)問題的重複。 –

+0

Catch-em-all異常處理是一種非常糟糕的做法,尤其是如果你對異常不夠了解的話。改爲編寫AppDomain.CurrentDomain.UnhandledException事件的事件處理程序。 –

+0

在我的上下文中(addin Microsoft Word),無法攔截AppDomain.CurrentDomain.UnhandledException事件。因此,爲了安全體驗用戶,需要攔截未處理的異常以發送到應用程序異常解析器。好的方法是使用Postsharp集中發送未處理的異常到Application Exception Resolver。但看起來像Postsharp不會攔截BackGroundWorker異常。 – Christ121212

回答

0

由於拋出異常時PostSharp在調用堆棧上沒有任何方法轉換,所以方面代碼根本不會執行。在沒有任何直接改變的情況下讓這個方面正確地工作在這個代碼上是有點棘手的,但是可能的。

默認情況下,PostSharp的多播引擎不會將方面應用於匿名方法和其他(VB或C#)編譯器生成的代碼。雖然您可以強制PostSharp應用於這些方法,但不推薦。

另一種方式是直接針對BackgroundWorker及其DoWork事件。雖然不能直接更改實現,但可以攔截來自代碼的對事件方法的調用。以下是這種攔截的簡單實現,它包裝傳入的委託,以便它可以被您的方面攔截(MyOnExceptionAspect): public class EventInterceptionProxy {0}私有DoWorkEventHandler處理程序;

public EventInterceptionProxy(DoWorkEventHandler handler) 
    { 
     this.handler = handler; 
    } 

    [MyOnExceptionAspect] 
    public void Intercept(object sender, DoWorkEventArgs ea) 
    { 
     handler?.Invoke(sender, ea); 
    } 
} 

[Serializable] 
public class AddHandlerInterception : MethodInterceptionAspect 
{ 
    public override void OnInvoke(MethodInterceptionArgs args) 
    { 
     args.Arguments[0] = 
      new DoWorkEventHandler(new EventInterceptionProxy((DoWorkEventHandler) args.Arguments[0]).Intercept); 

     args.Proceed(); 
    } 
} 

您可以然後使用以下應用方面:

[assembly: AddHandlerInterception(
       AttributeTargetTypes = "System.ComponentModel.BackgroundWorker", 
       AttributeTargetAssemblies = "System", 
       AttributeTargetMembers = "add_DoWork")] 

所有上面的代碼只是一個示範。它不處理處理程序移除和其他方案(PCL庫中的使用,線程安全,弱事件...)。