How to propagate an exception raised in a worker thread to the UI thread
-
Hi all, Hopefully this is the right thread for this question. I was quite uncertain to whether it was a .NET question or a C# question. However, I could see more thread related questions under the c# subject. Well, I am new to the c# and the .net platform. I wonder if some kind soul could help me with my question. I am trying to develop a monitoring application that will be able to monitor all servers and Oracle databases on a network. I am using SQLITE for the local database and perl to act as the agent that keeps checking things out. For the front end, (The Configuration Assistant tool) I am using C#. I often need to connect to Oracle Databases from my UI thread. I am avoiding to lock the UI by executing the DML under a second thread as follows:
try
{
foreach (ListViewItem monitoredDatabases in monitoredDatabasesListView.Items)
}
String[] connectionResults = new String[10];
Thread testOracleConnection = new Thread(delegate()
try
{
// Invoke a method of another class that catches Oracle errors and re-throw the exception.} catch (OracleException) // CATCH inside thread 1 { // If the testOracleConnection has raised an exception, I would like to re-throw the exception // so that the outer CATCH statement will deal with this. throw; // This causes the entire application to crash // However, I can clearly see that the code definitelly gets here } }); testOracleConnection.Start(); while (testOracleConnection.IsAlive) { Application.DoEvents(); Thread.Sleep(1); }
}
catch (Exception) CATCH on thread 0
{
// The code never gets here when an OracleException was caught and re-thrown on above catch statement.
progressInfoForm.Close();
Cursor = Cursors.Default;
return (false);
}As you can see on the above code, the exception never gets to the CATCH statement on thread 0 and causes the entire application to crash. What I want to do here is have one single place to restore all the normal behaviour of the form once it has encountered an exception. Eg, within the CATCH statement of the thread 0 (UI), I then reset the Cursor style, close the progress bar form and return with the correct status to the calling method. It would be great if someone could actually show me how I could solve this problem by changing the code snipped above so that I can try it out and definitelly unders
-
Hi all, Hopefully this is the right thread for this question. I was quite uncertain to whether it was a .NET question or a C# question. However, I could see more thread related questions under the c# subject. Well, I am new to the c# and the .net platform. I wonder if some kind soul could help me with my question. I am trying to develop a monitoring application that will be able to monitor all servers and Oracle databases on a network. I am using SQLITE for the local database and perl to act as the agent that keeps checking things out. For the front end, (The Configuration Assistant tool) I am using C#. I often need to connect to Oracle Databases from my UI thread. I am avoiding to lock the UI by executing the DML under a second thread as follows:
try
{
foreach (ListViewItem monitoredDatabases in monitoredDatabasesListView.Items)
}
String[] connectionResults = new String[10];
Thread testOracleConnection = new Thread(delegate()
try
{
// Invoke a method of another class that catches Oracle errors and re-throw the exception.} catch (OracleException) // CATCH inside thread 1 { // If the testOracleConnection has raised an exception, I would like to re-throw the exception // so that the outer CATCH statement will deal with this. throw; // This causes the entire application to crash // However, I can clearly see that the code definitelly gets here } }); testOracleConnection.Start(); while (testOracleConnection.IsAlive) { Application.DoEvents(); Thread.Sleep(1); }
}
catch (Exception) CATCH on thread 0
{
// The code never gets here when an OracleException was caught and re-thrown on above catch statement.
progressInfoForm.Close();
Cursor = Cursors.Default;
return (false);
}As you can see on the above code, the exception never gets to the CATCH statement on thread 0 and causes the entire application to crash. What I want to do here is have one single place to restore all the normal behaviour of the form once it has encountered an exception. Eg, within the CATCH statement of the thread 0 (UI), I then reset the Cursor style, close the progress bar form and return with the correct status to the calling method. It would be great if someone could actually show me how I could solve this problem by changing the code snipped above so that I can try it out and definitelly unders
See: Proper Threading in Winforms .NET[^] If this doesn't help you solve the problem let us know. Also do some research on: AppDomain has an UnhandledException Application has a ThreadException Using these you will have the ability to catch any exception before it blows up the application. It's caught in the 'Main' Class of you application. ~TheArch :cool:
-
Hi all, Hopefully this is the right thread for this question. I was quite uncertain to whether it was a .NET question or a C# question. However, I could see more thread related questions under the c# subject. Well, I am new to the c# and the .net platform. I wonder if some kind soul could help me with my question. I am trying to develop a monitoring application that will be able to monitor all servers and Oracle databases on a network. I am using SQLITE for the local database and perl to act as the agent that keeps checking things out. For the front end, (The Configuration Assistant tool) I am using C#. I often need to connect to Oracle Databases from my UI thread. I am avoiding to lock the UI by executing the DML under a second thread as follows:
try
{
foreach (ListViewItem monitoredDatabases in monitoredDatabasesListView.Items)
}
String[] connectionResults = new String[10];
Thread testOracleConnection = new Thread(delegate()
try
{
// Invoke a method of another class that catches Oracle errors and re-throw the exception.} catch (OracleException) // CATCH inside thread 1 { // If the testOracleConnection has raised an exception, I would like to re-throw the exception // so that the outer CATCH statement will deal with this. throw; // This causes the entire application to crash // However, I can clearly see that the code definitelly gets here } }); testOracleConnection.Start(); while (testOracleConnection.IsAlive) { Application.DoEvents(); Thread.Sleep(1); }
}
catch (Exception) CATCH on thread 0
{
// The code never gets here when an OracleException was caught and re-thrown on above catch statement.
progressInfoForm.Close();
Cursor = Cursors.Default;
return (false);
}As you can see on the above code, the exception never gets to the CATCH statement on thread 0 and causes the entire application to crash. What I want to do here is have one single place to restore all the normal behaviour of the form once it has encountered an exception. Eg, within the CATCH statement of the thread 0 (UI), I then reset the Cursor style, close the progress bar form and return with the correct status to the calling method. It would be great if someone could actually show me how I could solve this problem by changing the code snipped above so that I can try it out and definitelly unders
hi daniel, I've read your code and performed following test. looks you can not just throw your exception in the new thread. you can handle it in the worker thread and use delegate to process it in GUI thread. The following is my test code. 2 buttons in one single form. "Button1" can cause the program crash. "Button2" success capture the error. Hope it helps.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}private void button1\_Click(object sender, EventArgs e) { Thread t = new Thread(delegate() { DoWork(); }); try { t.Start(); } catch (Exception ex) { commonExceptionHandler(ex); } } private void button2\_Click(object sender, EventArgs e) { Thread t = new Thread(delegate() { try { DoWork(); } catch (Exception ex) { commonExceptionHandler(ex); } }); t.Start(); } private void commonExceptionHandler(Exception ex) { if (this.InvokeRequired) { this.Invoke(new Action(() => commonExceptionHandler(ex))); } else { //your code here MessageBox.Show("\[got it!\] "+Environment.NewLine+ ex.ToString()); } } private void DoWork() { throw new InvalidOperationException("this is test"); } }
-
Hi all, Hopefully this is the right thread for this question. I was quite uncertain to whether it was a .NET question or a C# question. However, I could see more thread related questions under the c# subject. Well, I am new to the c# and the .net platform. I wonder if some kind soul could help me with my question. I am trying to develop a monitoring application that will be able to monitor all servers and Oracle databases on a network. I am using SQLITE for the local database and perl to act as the agent that keeps checking things out. For the front end, (The Configuration Assistant tool) I am using C#. I often need to connect to Oracle Databases from my UI thread. I am avoiding to lock the UI by executing the DML under a second thread as follows:
try
{
foreach (ListViewItem monitoredDatabases in monitoredDatabasesListView.Items)
}
String[] connectionResults = new String[10];
Thread testOracleConnection = new Thread(delegate()
try
{
// Invoke a method of another class that catches Oracle errors and re-throw the exception.} catch (OracleException) // CATCH inside thread 1 { // If the testOracleConnection has raised an exception, I would like to re-throw the exception // so that the outer CATCH statement will deal with this. throw; // This causes the entire application to crash // However, I can clearly see that the code definitelly gets here } }); testOracleConnection.Start(); while (testOracleConnection.IsAlive) { Application.DoEvents(); Thread.Sleep(1); }
}
catch (Exception) CATCH on thread 0
{
// The code never gets here when an OracleException was caught and re-thrown on above catch statement.
progressInfoForm.Close();
Cursor = Cursors.Default;
return (false);
}As you can see on the above code, the exception never gets to the CATCH statement on thread 0 and causes the entire application to crash. What I want to do here is have one single place to restore all the normal behaviour of the form once it has encountered an exception. Eg, within the CATCH statement of the thread 0 (UI), I then reset the Cursor style, close the progress bar form and return with the correct status to the calling method. It would be great if someone could actually show me how I could solve this problem by changing the code snipped above so that I can try it out and definitelly unders
Since you are running this from a UI form, I would use a BackgroundWorker. This allows you to trap an event when the BackgroundWorker ends, and you can tell whether it completed normally, or whether it failed with an exception and if so what exception it received.