一个简单的BUTTON的CLICK事件
private void btnInstall_Click(object sender, EventArgs e)
{
            int z = 0;
            txtMsg.Text = "循环开始执行。。"+DateTime.Now.ToString();
            for (int i = 0; i < 10000; i++)
            {
                z++;
            }
            txtMsg.Text = "循环执行结束。。" + DateTime.Now.ToString();
}
例如i循环10000次需要2分钟(打个比方而已,或许只要几秒),程序开始在文本框中显示了一句话,结束后显示了一句话,但在界面上显示的两句话是程序执行结束后一起显示的!
我希望在执行循环前界面就能显示 开始执行 ,结束后,再显示 执行结束,这个应该怎么实现?
是否需要使用异步,该怎么实现?

解决方案 »

  1.   

    将for循环处理独立成一个函数,用单独的线程去执行,执行之前显示第一个文字,执行后,显示第二个文字。关于如何实现跨线程访问,看这里:c#中使用多线程访问 winform中控件的若干问题 
      

  2.   

    private void btnInstall_Click(object sender, EventArgs e)
    {
      int z = 0;
      txtMsg.Text = "循环开始执行。。"+DateTime.Now.ToString();
      Application.DoEvents();
      for (int i = 0; i < 10000; i++)
      {
      z++;
      }
      txtMsg.Text = "循环执行结束。。" + DateTime.Now.ToString();
    }
    试试看
      

  3.   

    完整代码:
            private void btnInstall_Click(object sender, EventArgs e)
            {
                txtMsg.Text = "循环开始执行。。" + DateTime.Now.ToString();            Thread thread = new Thread(new ThreadStart(ProcessData));
                thread.Start();
            }        private void ProcessData()
            {
                int z = 0;
                
                for (int i = 0; i < 1000; i++)
                {
                    z++;
                    Thread.Sleep(5);
                }
                this.Invoke((EventHandler)delegate(object s, EventArgs e)
                {
                    txtMsg.Text = "循环执行结束。。" + DateTime.Now.ToString();
                });
                
            }
      

  4.   

    //注释版本:        private void button1_Click(object sender, EventArgs e)
            {
                txtMsg.Text = "循环开始执行。。" + DateTime.Now.ToString();
                //启动一个后台线程执行数据处理
                Thread thread = new Thread(new ThreadStart(ProcessData));
                thread.Start();
            }        private void ProcessData()
            {
                int z = 0;
                
                for (int i = 0; i < 1000; i++)
                {
                    z++;
                    //因为处理很快,为了模拟数据处理的实践,增加了延时
                    Thread.Sleep(5);
                }
                //退出循环后,跨线程修改文本框内容
                this.Invoke((EventHandler)delegate(object s, EventArgs e)
                {
                    txtMsg.Text = "循环执行结束。。" + DateTime.Now.ToString();
                });      
            }
      

  5.   

            模拟系统休眠  调用方法Sleep();    
      

  6.   

    异步方式
    1private SortedList sl = null;
     2  private const int  TEST_COUNT = 10000;
     3  private void button1_Click(object sender, System.EventArgs e)
     4  {
     5   mi = new MethodInvoker(DoWork);
     6   mi.BeginInvoke(new AsyncCallback(DoneWork), null);
     7  }
     8  private void DoWork()
     9  {
    10   sl = new SortedList();
    11   InitialPB(TEST_COUNT);
    12   for (int i =0;i<TEST_COUNT;i++)
    13   {
    14    sl.Add(i,"NoWay" + i.ToString());
    15    Thread.Sleep(100);
    16    RefreshText("NoWay" + i.ToString());
    17    RefreshPB(1);
    18   }
    19   
    20  }
    21  private void InitialPB(int max)
    22  {
    23   if( InvokeRequired )
    24   {
    25    this.Invoke( new IntDelegate(InitialPB), new object [] { max } );
    26    return ;
    27   }
    28   progressBar1.Maximum = max ;
    29   progressBar1.Value = 0;
    30  }
    31  private void RefreshText(string item)
    32  {
    33   if( InvokeRequired )
    34   {
    35    this.Invoke( new StringDelegate(RefreshText), new object [] { item } );
    36    return ;
    37   }
    38   this.textBox1.Text = item;
    39  }
    40  private void RefreshPB(int Value)
    41  {
    42   if( InvokeRequired )
    43   {
    44    this.Invoke( new IntDelegate(RefreshPB), new object [] {Value} );
    45    return ;
    46   }
    47   progressBar1.Value+=Value;
    48  }
    49  private void DoneWork(IAsyncResult result)
    50  {
    51   if( InvokeRequired )
    52   {
    53    Invoke(new AsyncCallback(DoneWork), new Object [] { result } );
    54    return ;
    55   }
    56   MessageBox.Show("Done!")
    57;
    58  }
    59  private void button2_Click(object sender, System.EventArgs e)
    60  {
    61   mi.EndInvoke(null);
    62  }
    63  private MethodInvoker mi= null;
    64  private delegate void IntDelegate(int num);
    65  private delegate void StringDelegate(string str);
    66
      

  7.   

    Application.DoEvents()处理当前在消息队列中的所有Windows 消息。 
    for (int q = 0; q < 1000000; q++)
                {
                    textBox1.Text = q.ToString();
                    Application.DoEvents();//实时响应文本框中的值
                }
      

  8.   

    geniusatm4的方法可以实现,但是当你执行未结束时点击关闭按钮的时候,会出现假死状态!computerfox的方法可以实现,当执行未结束时点击关闭,程序会正常关闭,但是过后会出现 遇到问题需要关闭 对话框!
      

  9.   

    用你的代码写的一个测试程序 
    private void button2_Click(object sender, EventArgs e)
            {
                int z = 0;
                txtMsg.Text += "循环开始执行。。" + DateTime.Now.ToString();
                //Application.DoEvents();
                //for (int i = 0; i < 1000; i++)
                //{
                //    z++;
                //    Thread.Sleep(5);
                //}
                //txtMsg.Text += "循环执行结束。。" + DateTime.Now.ToString();            Thread thread = new Thread(new ThreadStart(ProcessData));
                thread.Start();        }        private void ProcessData()
            {
                int z = 0;            for (int i = 0; i < 1000; i++)
                {
                    z++;
                    //因为处理很快,为了模拟数据处理的实践,增加了延时
                    Thread.Sleep(5);
                }
                //退出循环后,跨线程修改文本框内容
                this.Invoke((EventHandler)delegate(object s, EventArgs e)
                {
                    txtMsg.Text = "循环执行结束。。" + DateTime.Now.ToString();
                });
            }然后我不等待他执行完毕 就关闭窗体 ,就出现WindowApplication 遇到问题需要关闭。我们对此引起的不便表示抱歉。 
      

  10.   

    然后我不等待他执行完毕 就关闭窗体 ,就出现WindowApplication 遇到问题需要关闭。我们对此引起的不便表示抱歉。 一般这种情况下,你必须等待后台执行处理完毕后,才可以关闭窗体的,如果你要实现异步线程后台取消,请看这里,这是codeproject上的一个例子,很不错的,拷贝大文件时,你可以随时取消拷贝动作:
    源码和实现参考:
    Another way to Invoke UI from a Worker Thread