0

I evaluate Postsharp for to deploy in a application. I would like to handling all uncaught exceptions in my application with postsharp In this way , I implemented OnException method in a child class of OnExceptionAspect. With my tests, all exceptions are caught, except one exception in one case : when the exception is throw in a backgroundWorker.

my class :

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();
  }
}

Could you have a suggestion for to intercept this exception?

Thank you for your help.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • 1
    Hi there, welcome to Stack. Not a terrible first question, but i have edited your title slightly and changed your flags. You are just trying to handle an exception thrown by the background worker, this is essentially a duplicate of [this](http://stackoverflow.com/questions/20582253/background-worker-exception-handling) question. –  Nov 18 '16 at 15:46
  • Catch-em-all exception handling is a *terrible* practice, especially if you don't understand exceptions well enough yet. Write an event handler for the AppDomain.CurrentDomain.UnhandledException event instead. – Hans Passant Nov 18 '16 at 18:06
  • In my context (addin Microsoft Word) it's not possible to intercept AppDomain.CurrentDomain.UnhandledException event. so, to securise experience user, it's necessary to intercept unhandled exception for to send to an Application Exception Resolver. Good way is use Postsharp to centralise send unhandling exception to Application Exception Resolver. But it seems like Postsharp don't intercept BackGroundWorker exception. – Christ121212 Nov 21 '16 at 10:36
  • so, my problem is not solved ! – Christ121212 Nov 21 '16 at 10:37

1 Answers1

0

Since there is no method transformed by PostSharp on the call stack when the exception is thrown, the aspect code does not execute at all. Getting the aspect to work on exactly this code without any direct changes is a bit tricky, but possible.

By default PostSharp's multicasting engine does not apply aspects to anonymous methods and other (VB or C#) compiler-generated code. While you can force PostSharp to apply on these methods, it's not recommended.

The other way is to target directly BackgroundWorker and its DoWork event. While you cannot directly change the implementation, you may intercept calls to event's methods from you code. Following is a simple implementation of such interception that wraps the incoming delegate so that it can be intercepted by your aspect (MyOnExceptionAspect): public class EventInterceptionProxy { private DoWorkEventHandler handler;

    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();
    }
}

You can then apply the aspect using the following:

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

All of the above code is just a demonstration. It does not handle handler removal and other side cases (usage in PCL libraries, thread safety, weak events...).

Daniel Balas
  • 1,805
  • 1
  • 15
  • 20