Hi I'm working with winform and trying to use MessageBox for exception handling. The weird thing here is, the MessageBox appears only after the main form ("Form1" in the code below) is closed.
public class Worker {
/* edited (see below)
public void doWork() {
try {
// do something
client.Connect(serverAddress);
stream = client.GetStream();
}
catch(Exception e) {
MessageBox.Show(e.ToString(),
"This will not show up until Form1 is closed");
}
}
*/
}
public class Form1 {
/* edited (see below)
* public void threadProc() {
* Worker worker = new Worker();
* worker.doWork();
* }
*/
void button_Click(object sender, EventArgs e) {
// create a thread that will end up throwing an exception
Thread thread = new Thread(threadProc);
thread.Start();
}
}
What could be a better way to use MessageBox for exception handling?
...So I added some codes for MessageBox-ing in the UI thread, but the problem remains.
public class WorkExceptionArgs : EventArgs {
public Exception e;
public WorkExceptionArgs (Exception e) { this.e = e; }
}
public partial class Worker1 { // renamed (Worker->Worker1)
/* (edited) Now Worker1 doesn't trigger any event (see below)
public event EventHandler<WorkExceptionArgs> workException;
*/
public void doWork() {
try {
// do something
client.Connect(serverAddress);
stream = client.GetStream();
}
catch(Exception e) {
/* (edited) suppose Worker1 never throws any exception (see below)
* // trigger event that will cause MessageBox-ing by UI thread
* workException(this, new WorkExceptionArgs(e));
*/
}
}
}
public partial class Form1 {
public void threadProc() {
Worker1 worker1 = new Worker();
/* (edited) Now Worker1 never throws any exception
* worker.workException += new EventHandler<WorkException>(worker_WorkException);
*/
worker1.doWork();
// (added) After doWork() is done, Form1 creates Worker2
Worker2 w2 = new Worker2(this, this.form2);
w2.workException += new EventHandlerArgs<WorkExceptionArgs>(form2.worker2_WorkException);
w2.doSomeOtherWork();
}
/* public void worker_WorkException(object sender, WorkExceptionArgs eArg) {
* MessageBox.Show(eArg.e.ToString(), "Still not showing");
* } */
Form2 form2 = new Form2(); // (added) At first form2 is hidden (see below)
}
Actually there have been another form and another worker. Once Worker(Worker1) made connection to the server, Form1 hides (.Hide()), Form2 shows (.Show()), and Worker2 starts working with the connection Worker1 made.
public class Worker2 {
Worker2(Worker1 w1, Form2 frm2) { this.w1=w1; this.frm2=frm2; }
public Worker1 w1;
public Form2 frm2;
public event EventHandler<WorkExceptionArgs> workException;
public void doSomeOtherWork() { // do some other, using data in Worker 1.
try { // This will throw an exception
BinaryFormatter formatter = new BinaryFormatter();
MyObj mo = (MyObj)formatter.Deserialize(w1.getStream());
}
catch(Exception e) {
workException(this, new WorkExceptionArgs(e));
}
}
}
public class Form2 {
public Form2(Form1 frm1) { // to switch from frm1 to frm2
InitializeComponent();
this.frm1 = frm1;
}
public Frm1 frm1 {get;set;}
public void worker2_WorkException(object sender, WorkExceptionArgs ea) {
MessageBox.Show(this, ea.e.ToString(), "SHOWS ONLY IF FORM2 IS CLOSED");
}
}
public partial class Form1 {
delegate void switchWindow_Callback();
public void switchWindow() { this.Hide(); form2.Show(); }
public void switchWindowCb(object sender, EventArgs e) {
if(this.InvokeRequired) {
SwitchWindow_Callback hcb = new SwitchWindow_Callback(switchWindow);
this.Invoke(hcb, new object[] {});
}
else { this.switchWindow(); }
}
}