2012-09-10 2 views
1

안녕하세요 저는 winform을 사용하고 있으며 예외 처리를 위해 MessageBox를 사용하려고합니다. 이상한 것은 MessageBox가 기본 폼 (아래 코드의 "Form1")이 닫힌 후에 만 ​​나타납니다.MessageBox를 사용하여 멀티 스레드 응용 프로그램에서 예외 정보 표시

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

예외 처리를 위해 MessageBox를 사용하는 더 좋은 방법은 무엇일까요?


는 ... 그래서 메시지 박스 - 보내고 UI 스레드에 을위한 몇 가지 코드를 추가,하지만 문제는 남아있다.

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

사실은 또 다른 형태의 또 다른 노동자가 있었다. Worker (Worker1)가 서버에 연결되면 Form1이 숨김 (.Hide())되고 Form2가 Show()를 표시하고 Worker2는 Worker1이 만든 연결로 작업을 시작합니다.

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

코드를 디버그 모드로 밟았습니까? – Derek

답변

관련 문제