4

The below example is a simplification of my problem. An exception is thrown within a new thread. If im not handling this within the thread it is not caught by the outer try/catch and crashes my application.

Is there any way to guarantee that I catch any exception that occurs.

        try
        {
            new Thread(delegate()
                {
                    throw new Exception("Bleh"); // <--- This is not caught

                }).Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
CathalMF
  • 9,705
  • 6
  • 70
  • 106

4 Answers4

8

Generally speaking, it's easiest to catch the exceptions within the thread itself.

But if you want to catch the exception separately from the thread function itself (and if you can use Task instead of the old Thread approach), you can write code like this:

var task = Task.Factory.StartNew(() =>
{
    throw new Exception("Test");
});

task.ContinueWith(t => handleException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

This uses ContinueWith() to call another method after the first thread has finished and an exception occurred, so you can log the exception or whatever:

static void handleException(AggregateException exception)
{
    foreach (var ex in exception.Flatten().InnerExceptions)
        Console.WriteLine(ex.Message);
}

This doesn't really let you fix anything up - the only sensible way to do that is to handle the exceptions properly in the thread function itself.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
2

I put it this way, and I believe this is the safest:

 var thread =   new Thread(MyMethod);
 thread.start();

This the method. The try-catch should be inside any thread-method

 private void MyMethod()
 {
    try
    {
        {
            throw new Exception("Bleh");//<--- This's not caught => now it is caught :)
        }
    }
    catch (Exception ex)
    {
        Logger.Log(ex.ToString());
    }
}
Has AlTaiar
  • 4,052
  • 2
  • 36
  • 37
  • Yes that's the correct way to do it but im trying to figure out a way to almost have a global catch. – CathalMF Jun 25 '13 at 13:29
1

Use AppDomain.UnhandledException, Application.ThreadException or Dispatcher.UnhandledException. It depends on the actual type of application.

Another possibility is to use AOP (PostSharp comes to mind). However, catching exceptions is not not the one and only goal. You need to find a way to fix the cause of the exception. If it is a bug, the exception is helpful and logging sufficient. If there is a more sophisticated reason you need to think about it and apply countermeasures. Unfortunately, there's no "general solution". So if you are'nt catching exceptions beforehand, I doubt you can act on it well.

JeffRSon
  • 10,404
  • 4
  • 26
  • 51
  • This allows me to log the exception but the exception still falls through and crashes the application. – CathalMF Jun 25 '13 at 13:14
  • Yes I know I should be catching exceptions within the threads themselves but in a more complex development its possible I could miss something and I don't want that exception to crash the whole system just because I forgot a try/catch. – CathalMF Jun 25 '13 at 13:21
  • 2
    Well, applications with bugs crash. You can't do anything about it because after the exception occurred the application might be in an unknown state. What will you do then? To prevent it from crashing there are other means: unit tests, debugging, logging, ... – JeffRSon Jun 25 '13 at 13:25
  • 2
    Its better that it crashes instead of execution with invalid state.. – Simon Whitehead Jun 25 '13 at 13:29
0

In my understanding .Net does not allow communicating between two threads. Beacause threads are isolated from one another. You can acheive this in a simple way and i don't know how much it will fit for you. Please mark the answer if it useful.

public  Exception exception;

private void button1_Click(object sender, EventArgs e)
{
        try
        {
            new Thread(delegate()
            {
                try
                {
                    throw new Exception("Bleh"); // <--- This is not caught
                }
                catch (Exception e)
                {
                    exception = e;
                }

            }).Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

        if (exception != null)
        {
            //your code here
        }

    }
Vimal CK
  • 3,543
  • 1
  • 26
  • 47