Catch UnhandledExceptions raised in threads, tasks, timers, ThreadPool and BackgroundWorkers threads

I have a WPF C # 4.0 application that I use to examine raw exception handling. I would like to have only one place in my code that handles the unhandled exceptions raised in any thread, regardless of how the thread was created. In my App.xaml.cs file, I have these exception handlers that spit out messages to the console:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        AppDomain.CurrentDomain.UnhandledException += this.CurrentDomain_UnhandledException;
        Application.Current.DispatcherUnhandledException += this.Current_DispatcherUnhandledException;
    }

    void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        Console.WriteLine("Current_DispatcherUnhandledException");
        e.Handled = true;
    }

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Console.WriteLine("CurrentDomain_UnhandledException");
    }
}

WPF , -: Task, Thread, ThreadPool, BackgroundWorker System.Threading.Timer. , .. NotImplementedException . , - .

, , , :

private void Button_Task_Click(object sender, RoutedEventArgs e)
{
    System.Threading.Tasks.Task.Factory.StartNew(() =>
        {
            throw new NotImplementedException(); //not caught
        });
}

private void Button_Thread_Click(object sender, RoutedEventArgs e)
{
    var thread = new System.Threading.Thread(
        new System.Threading.ParameterizedThreadStart((x) =>
        {
            throw new NotImplementedException();
            //CurrentDomain_UnhandledException caught
        }));
    thread.Start();
}

private void Button_ThreadPool_Click(object sender, RoutedEventArgs e)
{
    System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback((x) =>
        {
            throw new NotImplementedException();
            //CurrentDomain_UnhandledException caught
        }));
}

private void Button_BWorker_Click(object sender, RoutedEventArgs e)
{
    var bg = new System.ComponentModel.BackgroundWorker();
    bg.DoWork += new System.ComponentModel.DoWorkEventHandler(bg_DoWork);
    bg.RunWorkerAsync();
}
private void bg_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    throw new NotImplementedException(); //not caught
}

private void Button_Timer_Click(object sender, RoutedEventArgs e)
{
    var timer = new System.Threading.Timer((x) =>
        {
            throw new NotImplementedException();
            //CurrentDomain_UnhandledException caught
        }, null, 0, System.Threading.Timeout.Infinite);
}

. , ThreadPool , BackgroundWorkers Tasks ? Tasks, Timers BackgroundWorkers, . MSDN , , WPF , ?

: Action.BeginInvoke(). , . :

private void Button_Action_Click(object sender, RoutedEventArgs e)
{
    Action action = () =>
        {
            throw new NotImplementedException();
            //not caught
        };
    action.BeginInvoke(this.DoNothing, null);
}
private void DoNothing(object arg) { }

# 2: , . , , , :

private void Button_AsParallel_Click(object sender, RoutedEventArgs e)
{
    const int loops = 20;
    var list = new List<int>();
    for (int i = 0; i < loops; i++)
    {
        list.Add(i);
    }

    foreach (var item in list.AsParallel().Select(s => s))
    {
        if (item == 15)
            throw new NotImplementedException();
            //CurrentDomain_UnhandledException caught
    }
}

private void Button_ParallelFor_Click(object sender, RoutedEventArgs e)
{
    const int loops = 100;
    var list = new List<int>();
    for (int i = 0; i < loops; i++)
    {
        list.Add(i);
    }

    System.Threading.Tasks.Parallel.For(0, loops, (int i) =>
        {
            if (list[i] == 90)
                throw new NotImplementedException();
                //CurrentDomain_UnhandledException caught
        });
}
+4
1

, , . , Application.OnStartup():

AppDomain.CurrentDomain.UnhandledException += 
    this.CurrentDomain_UnhandledException;

System.Threading.Thread, System.Threading.ThreadPool.QueueUserWorkItem System.Threading.Timer. BackgroundWorker , , :

public class MyBackgroundWorker : BackgroundWorker
{
    protected override void OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
            throw e.Error;
        else
            base.OnRunWorkerCompleted(e);
    }
}

IEnumerable.AsParallel System.Threading.Tasks.Parallel.For , AppDomain.CurrentDomain.UnhandledException .

Tasks. Action<T> s Func<T>, BeginInvoke . , AppDomain.CurrentDomain.UnhandledException .

0

All Articles