How do I get the name of the thread that the exception occurred on?

4.9k views Asked by At

I am handling thread exceptions but I want to get the name of the Thread that the exception occurred on. It appears that when the thread exception fires the event stays on the main thread although I think the exception could have occurred on a different thread.

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    ShowFaultDialog(e.Exception, "(Application) Thread Exception [" + System.Threading.Thread.CurrentThread.Name + "]");
}
4

There are 4 answers

0
James On BEST ANSWER

In static void Main():

Thread.CurrentThread.Name = "Main Thread";

VS 2010 shows the main thread as having a 'Name' of "Main Thread" but actually the thread name is null.

8
Pharap On

Use an incrememnted numerical variable (such as byte) to give each thread it's own name eg

string threadname = "Thread" + threadnumber

And then use the catch statement to notify you like so:

ShowFaultDialog(e.exception, threadname)

That way you'll be able to tell which thread it is, in theory.

7
Dennis On

If you mean handling of Application.ThreadException event: it fires only on exceptions, that was thrown from WinForms threads. Usually, there's one WinForms thread in application: the main thread.

UPDATE.

Here's sample that demonstrating Application.ThreadException and AppDomain.UnhandledException behavior difference:

1) Program class:

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.Run(new Form1());
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Debug.WriteLine(Thread.CurrentThread.Name);
    }

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        Debug.WriteLine(Thread.CurrentThread.Name);
    }
}

2) Main form (a form with two buttons) code-behind:

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

    private void button1_Click(object sender, EventArgs e)
    {
        throw new InvalidOperationException();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        new Thread(() => { throw new InvalidOperationException(); })
        {
            Name = "Worker Thread"
        }.Start();
    }
}

When you are clicking on button1, you're throwing exception from WinForms thread. So, this exception will be handled at Application_ThreadException by default.

When you are clicking on button2, you're throwing exception from worker thread, which is not a WinForms thread. Application.ThreadException isn't fired in this case, instead AppDomain.UnhandledException event is fired (and CurrentDomain_UnhandledException is called, producing 'Worker Thread' line in output window).

0
Steve On

As I understand from MSDN the Application_ThreadException event allows Windows Forms applications to handle unhandled exceptions that occur in Windows Forms threads and when you reach this event you are in your main UI thread. So it will print always the same.

Have you checked the Exception.TargetSite property? This property gives you back the method name and signature where the exception occurred.