C# – catch exception that is thrown in different thread

c++exception-handlingmultithreading

One of my method (Method1) spawns a new thread.
That thread execute a method (Method2) and during exectution an exception is thrown.
I need to get that exception information on the calling method (Method1)

Is there someway I can catch this exception in Method1 that is thrown in Method2?

Best Solution

In .NET 4 and above, you can use Task<T> class instead of creating new thread. Then you can get exceptions using .Exceptions property on your task object. There are 2 ways to do it:

  1. In a separate method: // You process exception in some task's thread

    class Program
    {
        static void Main(string[] args)
        {
            Task<int> task = new Task<int>(Test);
            task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
            task.Start();
            Console.ReadLine();
        }
    
        static int Test()
        {
            throw new Exception();
        }
    
        static void ExceptionHandler(Task<int> task)
        {
            var exception = task.Exception;
            Console.WriteLine(exception);
        }
    }
    
  2. In the same method: // You process exception in the caller's thread

    class Program
    {
        static void Main(string[] args)
        {
            Task<int> task = new Task<int>(Test);
            task.Start();
    
            try
            {
                task.Wait();
            }
            catch (AggregateException ex)
            {
                Console.WriteLine(ex);    
            }
    
            Console.ReadLine();
        }
    
        static int Test()
        {
            throw new Exception();
        }
    }
    

Note that the exception which you get is AggregateException. All real exceptions are availible through ex.InnerExceptions property.

In .NET 3.5 you can use the following code:

  1. // You process exception in the child's thread

    class Program
    {
        static void Main(string[] args)
        {
            Exception exception = null;
            Thread thread = new Thread(() => SafeExecute(() => Test(0, 0), Handler));
            thread.Start();            
    
            Console.ReadLine();
        }
    
        private static void Handler(Exception exception)
        {        
            Console.WriteLine(exception);
        }
    
        private static void SafeExecute(Action test, Action<Exception> handler)
        {
            try
            {
                test.Invoke();
            }
            catch (Exception ex)
            {
                Handler(ex);
            }
        }
    
        static void Test(int a, int b)
        {
            throw new Exception();
        }
    }
    
  2. Or // You process exception in the caller's thread

    class Program
    {
        static void Main(string[] args)
        {
            Exception exception = null;
            Thread thread = new Thread(() => SafeExecute(() => Test(0, 0), out exception));
    
            thread.Start();            
    
            thread.Join();
    
            Console.WriteLine(exception);    
    
            Console.ReadLine();
        }
    
        private static void SafeExecute(Action test, out Exception exception)
        {
            exception = null;
    
            try
            {
                test.Invoke();
            }
            catch (Exception ex)
            {
                exception = ex;
            }
        }
    
        static void Test(int a, int b)
        {
            throw new Exception();
        }
    }