Reputation: 46322
I have a method running in a seperate thread. The thread is created and started from a form in a windows application. If an exception is thrown from inside the thread, what is the best way to pass it back to the main application. Right now, I'm passing a reference to the main form into the thread, then invoking the method from the thread, and causing the method to be called by the main application thread. Is there a best practice way to do this because I'm not comfortable with how I'm doing it now.
Example of my form:
public class frmMyForm : System.Windows.Forms.Form
{
/// <summary>
/// Create a thread
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnTest_Click(object sender, EventArgs e)
{
try
{
//Create and start the thread
ThreadExample pThreadExample = new ThreadExample(this);
pThreadExample.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, Application.ProductName);
}
}
/// <summary>
/// Called from inside the thread
/// </summary>
/// <param name="ex"></param>
public void HandleError(Exception ex)
{
//Invoke a method in the GUI's main thread
this.Invoke(new ThreadExample.delThreadSafeTriggerScript(HandleError), new Object[] { ex });
}
private void __HandleError(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Example of my thread class:
public class ThreadExample
{
public delegate void delThreadSafeHandleException(System.Exception ex);
private Thread thExample_m;
frmMyForm pForm_m;
private frmMyForm Form
{
get
{
return pForm_m;
}
}
public ThreadExample(frmMyForm pForm)
{
pForm_m = pForm;
thExample_m = new Thread(new ThreadStart(Main));
thExample_m.Name = "Example Thread";
}
public void Start()
{
thExample_m.Start();
}
private void Main()
{
try
{
throw new Exception("Test");
}
catch (Exception ex)
{
Form.HandleException(ex);
}
}
}
Upvotes: 13
Views: 21098
Reputation: 75
I totally agree with Dror. In a formal way we can call this structure as FaultContract. Fundamentally when an exception has happened in another thread, the client thread can hardly do any thing at that moment except that to collect that information and act accordingly in it's own theread. If the thereads are in different AppPool then there is an extra complexity of Serialization (that can be a seperate topic altogether).
Upvotes: 0
Reputation: 2532
Use the BackgroundWorker class in the .NET framework instead. It is the best practice for performing UI work on a different thread.
Upvotes: 5
Reputation:
Probably a better way would be to pass a delegate into the thread instead of a reference to the form itself.
Upvotes: 2
Reputation: 1499730
So you're using Invoke to marshall back to the UI thread, by the looks of it - which is exactly what you need to do. I'd personally use an Action<Exception> for simplicity's sake, and possibly BeginInvoke instead of Invoke, but basically you're doing the right thing.
Upvotes: 17
Reputation: 30780
Throwing exceptions between threads is not easy and probably not desired. instead you can pass the exception using a shared data structure or variable and use waitHandle to wait on the 1st thread.
Upvotes: 1