views:

1350

answers:

5

Hi,

I am currently asking myself some questions about exception handling and eventhandlers, and i hope some of you will give me some help.

I will start to explain what i would like to achieve in my c# application:

I have a top-level method (lets call it the main method). This method calls an asynchronous method (wich is called connect), which connect to a FTP server.

An EventHandler object is associated to this connection, and a "callback" method is called when the connection is successful.

I want to handle exceptions that can be launched during the whole process. So i would like to catch it in the top level method. It works fine for exceptions launched by the connect method (which is called inside the top level method). However, it does not work for exceptions called inside the "callback" method: the top level method does not catch them and the execution fails.

What can I do to make these exceptions beeing caught by the top level method ? I don't want to handle these exceptions in the callback.

+1  A: 

There is an event handler in the Application class called ThreadException. This event will be fired whenever an exception is thrown an not caught anywhere in the current call stack.


Edited:

Sorry, I misread the question - I didn't realise that the "main" method in your example isn't the actual main method. In that case you may want to catch the exception inside the callback, but not handle it - instead simply pass it back up to the main method as part of the event args.

The BackgroundWorker in Winforms does something similar.

Martin Harris
+2  A: 

Take a look at how the Backgroundworker deals with this: the Exception is propagated to the Completed event handler.

I assume you have some form of State object that is passed to/from the delegate, that's where you can add such a property. And you will have to catch all exceptions in the thread, at the outermost scope. But 'handling' just means passing it along.

There is a standard pattern for the RunWorkerCompleted event, see this MSDN page.

Henk Holterman
A: 

Consider the below code fragment for wrapping all of your code in a global exception handler:

namespace MyClient
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        bool isSuccess = SubMain(string[] args);
      }
      catch (Exception e)
      {
        HandleExceptionGracefully(e);
      }
    }
    static bool SubMain(string[] agrs)
    {
       // Do something
    }
    static void HandleExceptionGracefully(Exception e)
    {
       // Display/Send the exception in a graceful manner to the user/admin.
    }
  }
}

Also, don't forget to make your error handling user-friendly.

Lucas B
A: 

Thanks for your answers.

It seems that using the BackgroundWorker solve this problem.

I did not try it, because i chose to avoid this implementation burden. So I took away my asynchronous call and made my application behaving synchronously.

One tip for people using the Compact Framework instead of the full .NET Framework: the BackgroundWorker is not available in CF, but a similar solution is provided by OpenNETCF (see the BackgroundWorker class in the Smart Device Framework).

OutOfBound
A: 

A more convenient way to deal with this problem of top-level exception handling is to use delegates.

These c# delegates allow to call methods in a asynchronous way. And delegates allow also top-level exception handling. Indeed, exceptions thrown inside delegates are re-thrown on the original thread.

I don't know why i did not think about delegates before. I hope it will help.

See these nice articles about delegates:

Article 1

Article 2

OutOfBound
but asynchronous delegates are not supported by the compact framework... :(
OutOfBound