2011-06-24 77 views
0

大家。線程完成時關閉窗體

我有兩個表單如下的

  1. 1跳轉有一個按鈕,當單擊該窗體2將會出現。

  2. From2有一個進度條,它的計數,直到它完成了從Maximun值更新進度,窗體2將關閉。

這下面窗體2

public delegate void ProgressbarHandler(int value); 
public partial class Form2 : Form 
{ 

    public event WaitCallback CloseThreadEvent; 

    private Thread t; 

    public void OnCloseEvent(ThreadState state) 
    { 
     if (CloseThreadEvent != null) 
      CloseThreadEvent(state); 
    } 

    public Form2() 
    { 
     InitializeComponent(); 

     progressBar1.Minimum = 0; 
     progressBar1.Maximum = 20000; 
    } 
    private void Form2_Load(object sender, EventArgs e) 
    { 
     InitThread(); 
    } 

    private void InitThread() 
    { 
     t = new Thread(new ThreadStart(RunThread)); 
     t.Start(); 

     CloseThreadEvent += new WaitCallback(CloseForm); 

     Thread tt = new Thread(ThreadObserver); 
     tt.IsBackground = true; 
     tt.Start(); 
    } 
    private void RunThread() 
    { 
     for (int i = 0; i < progressBar1.Maximum; i++) 
     { 
      progressBar1.Invoke(new ProgressbarHandler(UpdateProgressbar), i); 
     } 
    } 
    private void UpdateProgressbar(int value) 
    { 
     progressBar1.Value = value + 1; 
    } 

    private void ThreadObserver() 
    { 
     while (t.IsAlive) 
     { 
      OnCloseEvent(t.ThreadState); 
     } 
    } 
    private void CloseForm(Object state) 
    { 
     if ((ThreadState)state == ThreadState.Stopped) 
      this.Close(); 
    } 
} 

從我的代碼的代碼,它有一個「跨線程操作無效」上

this.Close(); 

請給出建議,如何編碼錯誤跟隨我的目的。

謝謝。

回答

2

相當簡單的修補。

this.Invoke(new MethodInvoker(delegate { this.Close(); })); 

我不知道你爲什麼沒有想到它?這不明顯嗎? :P

+0

我很新手。 :( – Yoonmy

+1

或甚至只是:調用(新MethodInvoker(關閉)); – Sean

3

只能從線程訪問控制,他們創建了。表單也是一個控件。

看一看Control.Invoke

我用類似這樣的一個類來處理這些情況:

public static class ControlExtensions 
{ 
    public static void Invoke(this Control control, Action action) 
    { 
     if (control.InvokeRequired) 
     { 
      control.Invoke(new MethodInvoker(action), null); 
     } 
     else 
     { 
      action.Invoke(); 
     } 
    } 
} 

那麼你就能夠調用this.Invoke(() => Close());關閉您的形式。

+0

甚至更​​短'調用(關閉)',因爲'Close'方法已經匹配'Action'代理 –

+0

well spotted :) –

0

謝謝各位

它的工作原理!

public partial class Form2 : Form 
{ 
    private Thread tstart, trun; 

    public Form2() 
    { 
     InitializeComponent(); 

     progressBar1.Minimum = 0; 
     progressBar1.Maximum = 100; 
    } 
    private void Form2_Load(object sender, EventArgs e) 
    { 
     tstart = new Thread(InitThread); 
     tstart.Start(); 
    } 

    private void InitThread() 
    { 
     trun = new Thread(new ThreadStart(RunThread)); 
     trun.Start(); 
     trun.Join(); 

     CloseForm(trun.ThreadState); 
    } 
    private void RunThread() 
    { 
     for (int i = 0; i < progressBar1.Maximum; i++) 
     { 
      Thread.Sleep(10); 
      progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Increment(1); }));        
     } 
    } 
    private void CloseForm(Object state) 
    { 
     if ((ThreadState)state != ThreadState.Stopped)    
      return;    
     else 
     { 
      if (this.InvokeRequired) 
       this.Invoke(new MethodInvoker(delegate { this.Close(); }), null); 
     } 
    } 

    private void Form2_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     if (tstart.IsAlive) 
      tstart.Abort(); 
     if (trun.IsAlive) 
      trun.Abort(); 
    } 

} 
+0

它不有意義地啓動一個線程來啓動一個線程。檢查線程狀態和InvokeRequired也沒有意義,您知道它是從線程調用的。 –

相關問題