2011-06-24 80 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也没有意义,您知道它是从线程调用的。 –

相关问题