Mit MessageBox zu zeigen, Ausnahme Angaben in Multithread-Anwendung

Hallo, ich arbeite mit Windows forms und versucht die MessageBox für die Ausnahmebehandlung.
Das seltsame dabei ist, dass der MessageBox erscheint nur nach der Haupt-form ("Form1" im code unten) geschlossen ist.

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();
     }
}

Was könnte ein besserer Weg, um MessageBox für die Ausnahmebehandlung?


...Also ich habe einige codes für die MessageBox-ing in den UI-thread, aber das problem bleibt.

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)
}

Eigentlich gab es eine andere form und ein anderer Arbeiter. Einmal Arbeiter(Worker1) aus Verbindung zu dem server, Form1 versteckt (.Hide()), Form2 zeigt (.Show()), und Worker2 beginnt die Arbeit mit der Verbindung Worker1 gemacht.

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(); }
    }
}
  • Haben Sie ging durch den code im debug-Modus?
Schreibe einen Kommentar