各位大侠, 兄弟刚学线程, 觉得好迷茫, 入不了门, 还望指点迷津。 
我写了一个例子, 想实现的效果是,点击按钮后, label1从10000依次显示到1,同时进度条progressBar1显示进度, 可实际准果是, 只进度条显示进度, 而label1没反应, 代码如下:
        private void button1_Click(object sender, EventArgs e)
        {
            //Thread T2 = new Thread(new ThreadStart(ThreadMethod));
            Thread T2 = new Thread(new ThreadStart(ExecuteMethod));
            T2.Start();
        }
        delegate void add();//委托
        private void ExecuteMethod()
        {
            this.BeginInvoke(new add(ThreadMethod));
        }        private void ThreadMethod()
        {
            progressBar1.Minimum = 0;
            progressBar1.Maximum = 10000;
            progressBar1.Step = 1;
            label1.Text = "10000";
            for (int i = 1; i < 10000; i++)
            {
                label1.Text = System.Convert.ToString(System.Convert.ToInt32(label1.Text.Trim()) - 1);
                progressBar1.PerformStep();
            }
            progressBar1.Value = 0;
        }但如果我采用不安全的线程调用,即去掉
        delegate void add();//委托
        private void ExecuteMethod()
        {
            this.BeginInvoke(new add(ThreadMethod));
        }
这三句, 直接在线程中, 调用ThreadMethod就可正常达到要求。当然, 得加上:
CheckForIllegalCrossThreadCalls = false;
但这种方式并不好, 我不想采用, 哪位大侠能告诉我, 上面怎么修改, 能达到我让label1和进度条同时变化的目的。 谢谢

解决方案 »

  1.   

    label1.Text = System.Convert.ToString(System.Convert.ToInt32(label1.Text.Trim()) - 1);
    来不及刷新lable上的文字,在这句后面加一个Application.DoEvents();或者你开两个线程,一个显示lable,一个控制processbar
      

  2.   

    代码有点乱,没有仔细看。你的ThreadMethod也是在主线程中执行的,那么主线程一直被占用着,来不及显示进度条。.net有很多多线程执行的方法,可以参考一种:http://www.google.com.hk/search?q=backgroundworker+progressbar&hl=zh-CN&safe=strict&prmd=ivnsfd&source=lnt&tbs=lr:lang_1zh-CN|lang_1zh-TW&lr=lang_zh-CN|lang_zh-TW&sa=X&ei=sZ9HTZ3mIMWlcNOhpfcC&ved=0CAcQpwUoAQ
      

  3.   

    “罪魁祸首”其实就是你的“this.BeginInvoke(new add(ThreadMethod));”这一句。既然要用线程来执行操作,那么就应该直接执行“ThreadMethod”方法!如果觉得比较难编程,还是先模仿好的例子,把你的程序搞得细一点。
      

  4.   

    那么主线程一直被占用着,来不及显示进度条   -->  那么主线程一直被占用着,来不及显示Label。
      

  5.   

    backgroundWorker 结合progressbar
    http://topic.csdn.net/u/20080306/17/0e289637-2d1e-4800-b017-472b83ed647f.html
      

  6.   

    我以前好像试过,如果不用beginInvoke的话,那label的值是不能改变的,因为label属于主线程
      

  7.   


    所以for循环——真正能够处理数据的程序——还是要在子线程中执行,而修改label、progressbar的代码才需要在主线中执行。而你没有把它们分解开,所以一会儿在子线程(先new了一个线程),一会儿在主线程(线程中由用begininvoke调用处理数据的程序。需要把你的ThreadMethod方法中的代码拆开,只有个别代码才在主线程执行,而for循环还是在子线程中执行。
      

  8.   

    找个例子,模仿一下就可以了。
    给你一些我的代码:
    //由于PictureBox1、Button_InsertSatelliteMapImage、ProgressBar1等均被涉及于线程,
    //所以需要进行线程安全设置。
    delegate void PictureBoxRefreshDelegate(); // 线程刷新picturebox1
    private void PictureBoxRefresh()           // 线程刷新picturebox1
    {
       if (PictureBox1.InvokeRequired)
       {
         PictureBoxRefreshDelegate d = new PictureBoxRefreshDelegate(PictureBoxRefresh);
         this.Invoke(d);
       }
       else
       {
         PictureBox1.Refresh();
       }
    }
    delegate void LabelTextChangedDelegate(string label_text);
    private void LabelTextChanged(string label_text) //在线程使用控件Label1
    {
      if (label1.InvokeRequired)
      {
         LabelTextChangedDelegate d = new LabelTextChangedDelegate(LabelTextChanged);
         this.Invoke(d, new Object[] { label_text });
      }
      else 
      {
         label1.Text = label_text; 
      }
    }
      

  9.   

    我想你把代码改一下
    string t;
    for (int i = 1; i < 10000; i++)
    {
    // label1.Text = System.Convert.ToString(System.Convert.ToInt32(label1.Text.Trim()) - 1);  t = System.Convert.ToString(System.Convert.ToInt32(label1.Text.Trim()) - 1);
      LabelTextChanged(t);
      //progressBar1.PerformStep(); //progressBar1的线程保护代码你就自己模仿一下吧。
    }
      

  10.   

    不卖关子了,还是给你吧
    delegate void ProgressBarValueChangedDelegate(int progress_percent);
    private void ProgressValueChanged(int progress_percent)
    {
      if (ProgressBar1.InvokeRequired )
      {
         ProgressBarValueChangedDelegate d =new ProgressBarValueChangedDelegate(ProgressValueChanged);
         this.Invoke(d, new Object[] { progress_percent });
      }
      else
      {
        ProgressBar1.Value = progress_percent;
      }
    }
    代码再次修改为:
    string t;
    for (int i = 1; i < 10000; i++)
    {
    // label1.Text = System.Convert.ToString(System.Convert.ToInt32(label1.Text.Trim()) - 1);  t = System.Convert.ToString(System.Convert.ToInt32(label1.Text.Trim()) - 1);
      LabelTextChanged(t);
      ProgressValueChanged(i);
    //  progressBar1.PerformStep();
    }