避免一个“长操作”影响界面响应和刷新的方法。

1. Application.DoEvent()

private void button1_Click(object sender, System.EventArgs e)
     {
       Test(100);
     }    private void Test(int max)
     {
       this.progressBar1.Maximum = max;
       while (this.progressBar1.Value < this.progressBar1.Maximum)
       {
         this.progressBar1.Value += 1;
         Application.DoEvents();
         System.Threading.Thread.Sleep(500);
       }
     }

2. Delegate Async

private delegate void TestHandler(int max);
    private void button1_Click(object sender, System.EventArgs e)
     {
       TestHandler t = new TestHandler(Test);
       t.BeginInvoke(100, null, null);
     }    private void Test(int max)
     {
       this.progressBar1.Maximum = max;
       while (this.progressBar1.Value < this.progressBar1.Maximum)
       {
         this.progressBar1.Value += 1;
         System.Threading.Thread.Sleep(500);
       }
     }

3. Thread

 

private void button1_Click(object sender, System.EventArgs e)
     {
       new Thread(new ThreadStart(ThreadProc)).Start();
     }    private void ThreadProc()
     {
       this.progressBar1.Maximum = 100;
       while (this.progressBar1.Value < this.progressBar1.Maximum)
       {
         this.progressBar1.Value += 1;
         System.Threading.Thread.Sleep(500);
       }
     }

上面的码虽然能正常工作,但是违反了一个规则。

Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。Control.InvokeRequired属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。控件上有四种方法可以安全地从任何线程进行调用:Invoke、BeginInvoke、EndInvoke 和 CreateGraphics。对于所有其他方法调用,当从另一个线程进行调用时,应使用这些 Invoke 方法之一。(摘自SDK帮助)

修改为: 

private delegate void ChangeProgressHandler(int max, int value);
    private void button1_Click(object sender, System.EventArgs e)
     {
       new Thread(new ThreadStart(ThreadProc)).Start();
     }    private void ThreadProc()
     {
       int i = 0;
       while (++i < 100)
       {
         this.Invoke(new ChangeProgressHandler(ChangeProgress), new object[]{100, i});
         System.Threading.Thread.Sleep(500);
       }
     }    private void ChangeProgress(int max, int value)
     {
       if (this.Tag == null)
       {
         MessageBox.Show(this.InvokeRequired.ToString());
         this.Tag = 1;
       }      this.progressBar1.Maximum = max;
       this.progressBar1.Value = value;
     }