How to catch exception in the main thread if the exception occurs in the secondary thread?
How to catch exception in the main thread if the exception occurs in the secondary thread?
The code snippet for the scenario is given below:
private void button1_Click(object sender, E开发者_如何学GoventArgs e)
{
try
{
Thread th1 = new Thread(new ThreadStart(Test));
th1.Start();
}
catch (Exception)
{
}
}
void Test()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
if (i == 2)
throw new MyException();
}
}
You can add a Application.ThreadException Event handler:
Joe is correct. Given the above windows forms code I was assuming Windows forms:
This event allows your Windows Forms application to handle otherwise unhandled exceptions that occur in Windows Forms threads. Attach your event handlers to the ThreadException event to deal with these exceptions, which will leave your application in an unknown state. Where possible, exceptions should be handled by a structured exception handling block.
See Unexpected Errors in Managed Applications
Use a BackgroundWorker.
A BackgroundWorker provides the infrastructure for communicating between the main UI thread and a background worker thread, including reporting exceptions. It is almost always a better solution than starting a thread from a button_click event handler.
As @codeka said, you can't. But if you want to do some UI stuff (May be displaying an error MessageBox to the user) in catch block in secondary thread, you can enclose like this. Better if you use BackgroundWorker
Invoke(new Action(() =>
{
MessageBox.Show("Message");
}));
You should consider adding your exception handling in your test method and deal with exceptions there.
The free Threading in C# ebook discusses this approach (and some others). Scroll down to the 'Exception Handling' section.
You might also use an asynchronous delegate to bubble up the information if you're concerned about globally trapping all exceptions.
see here
That is to say, trap the exception in thread B and use the Async Delegate to bubble information up to thread A. That way can can specifically target when the data from the exception is handled.
You can (now…this wasn't available when the question was originally asked) use async
and await
:
private async void button1_Click(object sender, EventArgs e)
{
try
{
await Task.Run(Test);
}
catch (Exception)
{
}
}
The Task.Run()
method will cause the Test()
method to be executed in a worker thread. If an unhandled exception is thrown in that thread, the Task
will propagate that exception back to the awaiting thread at the await
statement.
精彩评论