Click here to Skip to main content
15,889,266 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
There is an example in the C# MS documentation that explains how to use this to capture unhandled events. It proposes the code:

C#
Thread newThread = null;
// Starts the application. 
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);
    // Set the unhandled exception mode to force all Windows Forms errors to go through
    // our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}
// Programs the button to throw an exception when clicked.
private void button1_Click(object sender, System.EventArgs e)
{
    throw new ArgumentException("The parameter was invalid");
}
// Start a new thread, separate from Windows Forms, that will throw an exception.
private void button2_Click(object sender, System.EventArgs e)
{
    ThreadStart newThreadStart = new ThreadStart(newThread_Execute);
    newThread = new Thread(newThreadStart);
    newThread.Start();
}
// The thread we start up to demonstrate non-UI exception handling. 
void newThread_Execute()
{
    throw new Exception("The method or operation is not implemented.");
}
// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
private static void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t)
{
    DialogResult result = DialogResult.Cancel;
    try
    {
        result = ShowThreadExceptionDialog("Windows Forms Error", t.Exception);
    }
    catch
    {
        try
        {
            MessageBox.Show("Fatal Windows Forms Error",
                "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
        }
        finally
        {
            Application.Exit();
        }
    }
    // Exits the program when the user clicks Abort.
    if (result == DialogResult.Abort)
        Application.Exit();
}
// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
// NOTE: This exception cannot be kept from terminating the application - it can only 
// log the event, and inform the user about it. 
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    try
    {
        Exception ex = (Exception)e.ExceptionObject;
        string errorMsg = "An application error occurred. Please contact the adminstrator " +
            "with the following information:\n\n";
        // Since we can't prevent the app from terminating, log this to the event log.
        if (!EventLog.SourceExists("ThreadException"))
        {
            EventLog.CreateEventSource("ThreadException", "Application");
        }
        // Create an EventLog instance and assign its source.
        EventLog myLog = new EventLog();
        myLog.Source = "ThreadException";
        myLog.WriteEntry(errorMsg + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace);
    }
    catch (Exception exc)
    {
        try
        {
            MessageBox.Show("Fatal Non-UI Error",
                "Fatal Non-UI Error. Could not write the error to the event log. Reason: "
                + exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop);
        }
        finally
        {
            Application.Exit();
        }
    }
}
// Creates the error message and displays it.
private static DialogResult ShowThreadExceptionDialog(string title, Exception e)
{
    string errorMsg = "An application error occurred. Please contact the adminstrator " +
        "with the following information:\n\n";
    errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace;
    return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore,
        MessageBoxIcon.Stop);
}


I have worked through this a few times without any luck.

I am primarily interested in using the UI ThreadException.

I have added:

C#
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);


And created a simple Form1_UIThreadException handler. When I test this the exception thrown by button1 is still not caught.

I can see that C# is including the code and the handler but the Exception mechanism does not seem to fire for me.

If I simply use a try/catch on my Application.Run(new Formi()); in program.cs I can catch the Exceptions that bubble up.

I do have to comment out the ThreadException references first or that does not work. So it is in effect but not firing.

Has anyone worked through this example? Can you offer what I may be missing? :sigh:

Thanks.
Posted
Updated 18-Nov-10 4:09am
v2
Comments
Henry Minute 18-Nov-10 10:12am    
Just a thought. If you added a link to the page in the documentation that you got the code from, it might help people to help you. It would also enable you to cut your code snippet down to just the relevant parts. :)

Hi Toli;

Thanks for your reply. Not sure I understand.

Did you paste the shortened example into a Form project on VS 2010 Express and run it?
 
Share this answer
 
Comments
JOAT-MON 19-Nov-10 6:34am    
Yes, I pasted the one you said 'The code I am trying exactly boils down to:' from 'Answer 1' into VS 2010 Premium and it caught the exception and showed the MessageBox.
dpminusa 19-Nov-10 6:43am    
Do you think my problem could be that I am using VS 2010 Express rather than Premium?

I thought Express was a proper subset, but ...

What is your .NET version?

Thanks.
JOAT-MON 19-Nov-10 15:17pm    
I don't think the version of VS matters (whether Premium or Express). I tried targeting my project to .NET 2, .NET 3.5, and .NET 4 to see if it made a difference...it didn't matter, it still worked no matter which .NET was targeted.
dpminusa 19-Nov-10 15:57pm    
OK. Thanks for trying all that. It fails every time for me with my Vista Bus 32 SP2 system. Are you using Win 7 or Vista or XP? Maybe the .NET assemblies are different for some reason. I do see in the Help Doc that all the versions of .NET are supported as you say.

As a work-around I have made the Application.Run in my Program.cs into a try/catch. This accomplishes a similar thing.

My idea was to have a way to log an error that may have been missed somewhere else for debugging rather than just crash. The try/catch, the way I set it up, seems to offer that.

Thanks for the help.
JOAT-MON 19-Nov-10 16:43pm    
I run on XP SP3. From everything I have heard, most Vista versions have had a lot of unusual behaviors, so it may be a side effect of that. If you have the opportunity, you should try it on a different operating system and see if that has an effect. Good luck!
Will do. I am a bit frustrated with the Msoft example so I should have thought of that. Thanks.

I use the local Visual Studio Help so my URL is a 127.0.0.1 address. The topic is Application.ThreadException Event. If this was entered into the online VS10 doc link it would come up.

The code I am trying exactly boils down to:

program.cs:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
using System.Security.Permissions;

namespace WindowsFormsApplication1
{

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        static void Main()
        {
            // Add the event handler for handling UI thread exceptions to the event.
            Application.ThreadException += new ThreadExceptionEventHandler(Form1_UIThreadException);

            // Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }

        }

        // Handle the UI exceptions by showing a dialog box, and asking the user whether
        // or not they wish to abort execution.
        public static void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t)
        {
            MessageBox.Show(t.ToString());
        }
    }
}


Form1.cs:
C#
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            {
                InitializeComponent();
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            throw new ArgumentException("The parameter was invalid");
        }
    }
}
 
Share this answer
 
v2
Comments
JOAT-MON 18-Nov-10 21:23pm    
Not sure that this is a problem with your code. I copied it into my VS and it worked.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900