Handle ALL unhandled exceptions in non-winforms application (ex. windows service) in C#
===

I have seen tons of similar questions on stackoverflow, but none contained a satisfactory answer or provided a good code example.

The question is how to catch all unhandled exceptions in a non-winforms c# code? (In winforms this is easy).

Consider the complete code below:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                //TODO: configure unhandled exception handling here
                //Note: This is normally run as a windows service, no System.Windows.Application.Forms.ThreadException is available here
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
                TaskScheduler.UnobservedTaskException += new EventHandler<UnobservedTaskExceptionEventArgs>(TaskScheduler_UnobservedTaskException);
                try
                {
                    ExceptionHell exceptionHell = new ExceptionHell();
                    exceptionHell.RunExample();
                }
                catch (Exception ex)
                {
                    Die(ex.Message);
                }
                Console.ReadKey();
            }

            /// <summary>
            /// Does not seem to work
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
            {
                e.SetObserved();
                Die(e.Exception.Message);
            }

            /// <summary>
            /// Does not seem to work
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
                Die(((Exception)e.ExceptionObject).Message);
            }

            static void Die(string message)
            {
                //Log error here (maybe do some other stuff) and die
                Console.WriteLine(message);
            }
        }

        /// <summary>
        /// Assume you have no control over code in this class
        /// </summary>
        class ExceptionHell
        {
            public void RunExample()
            {
                Task.Factory.StartNew(() => TaskMethod());
                Thread thread = new Thread(new ThreadStart(ThreadMethod));
                throw new Exception("Main Thread Exception");
            }

            private void TaskMethod()
            {
                Task.Factory.StartNew(() => NestedTaskMethod());
                throw new Exception("Task Exception"); //TODO: Prepare code for this exception
            }

            private void ThreadMethod()
            {
                Thread thread = new Thread(new ThreadStart(NestedThreadMethod));
                throw new Exception("Thread Exception"); //TODO: Prepare code for this exception
            }

            private void NestedTaskMethod()
            {
                throw new Exception("Nested Task Exception"); //TODO: Prepare code for this exception
            }

            private void NestedThreadMethod()
            {
                throw new Exception("Nested Thread Exception"); //TODO: Prepare code for this exception
            }
        }
    }