定义了2个委托,一个用线程启动,一个用backgroundworker启动,为什么我用线程启动的委托刚开始只执行了一遍,等到用backgroundworker启动的委托执行完成后才会继续执行线程的委托?这个难道还有什么优先级?private int i = 0;
private delegate void InvokeLabel();
private delegate void InvokeMainForm();
private void Form_Load(object sender, EventArgs e){
    Thread setLabelTextThread = new Thread(setLabelText);
    setLabelTextThread.Start();
    this.backgroundWorker.RunWorkerAsync();
}
private void setLabelText()
{
    InvokeLabel il = delegate(){
        this.lable1.Text = i++.toString();
    };
    this.Invoke(il);
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e){
    while(true){
        InvokeMainForm imf = delegate(){                
            mainForm = new MainForm();
        };
        this.Invoke(imf);    
    }        
}       程序运行i++运行了一次,然后等到mainForm实例化后会继续执行?为什么?

解决方案 »

  1.   

    代码里用到了 this.Invoke ,这样他们就会转到主线程去执行,就有了先后顺序
      

  2.   


    this.Invoke改成this.BeginInvoke
      

  3.   

    7楼朋友的方法貌似还是不行啊,因为我实例化那个界面需要一些时间,所以LABEL的TEXT会等到实例化后才会继续增加,很纠结啊。还有没有别的方法了?还有我看回复有7条,为什么只显示了4条?另外3条哪去了?
      

  4.   

    我说说我要的效果吧,2个线程运行委托,一个委托在初始化界面,另一个会再一个LABEL上显示自增的数字。界面初始化结束,LABEL停止自增。感觉像进度条,但只是用文字显示。
      

  5.   

    初始化界面和自增数字都是在主线程里做的,所以这两个东西不可能并行的。楼主还是没明白进度条的原理。按照楼主的需求只能这么做。
    void dowork()
    {
    1,work1()
    Refresh()
    2,work2()
    Refresh()
    3,work3()
    Refresh()
    4,work4()
    Refresh()
    }void Refresh()
    {
    //刷新界面进度条
    }但是正常的需求是费时的加载操作放到子线程1去做,然后另一个子线程2轮询检查线程1工作的进度,然后更新UI。
      

  6.   

    既然不可以并行,我也做成过这样的,不调用线程来数字自增,然后在初始化界面的方法中,每个方法执行前让数字自增,然后显示,但是依然不管用,LABEL的I只显示最后一次增加的值。public class Form{
    public static i = 0;
    public static Label label;
    private delegate void InvokeMainForm();
    public Form(){
        InitializeComponent();
        label = new Label();
        this.Controls.Add(label);
    }
    private void Form_Load(object sender, EventArgs e){
        this.backgroundWorker.RunWorkerAsync();
    }
    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e){
            InvokeMainForm imf = delegate(){                
                mainForm = new MainForm();
            };
            this.Invoke(imf);    
        }        

    }
    public class MainForm(){
        public MainForm(){
            InitializeComponent();
            void1();
            void2();
            void3();
            void4();
        }
    }主页面的每个方法里会有执行Form.label.Text = Form.i++.toString();但是Form界面上只会显示最后一次的赋值(void4里的赋值),为什么前几次方法的值都不显示?一般的程序启动都会有进度条(比如Eclipse)他加载程序时,进度条界面不是有文字一直在显示做什么,那个是什么原理?
      

  7.   

    你要给主线程刷新UI的机会。而且,你       
    void1();
    void2();
    void3();
    void4();
    这几个过程很快,那你的值很快就变过去了。不是没变,是变得太快了。
      

  8.   

    先不说其他,就是楼主描述的效果与代码刚好相反,如果new MainForm()初始主界面,那外面的while(true)是干嘛的啊?
      

  9.   

    如果你两个 Invoke (阻塞直到主线程执行完),它们还能并行执行?如果两个 Invoke 语句可并行执行,那么就意味着主线程自己可以并行用两个线程来执行。这根本说不通话。
      

  10.   

    Invoke就是阻塞. 阻塞是多线程编程的大忌. 只有在你确实无法使用 BegineInvoke 的时候才应该去使用 Invoke.
      

  11.   

    咦,按理说BeginInvoke不会啊,像18说的一样,时间太短的话,进度是看不出来的喔
      

  12.   

    各位不好意思,怪我代码贴的不全,重新贴下public partial class LoginLoading : Form
        {
            public static MainForm mainForm;        private Thread progressBarThread;        private int progressBarValue = 1;        private bool flag;        public delegate void InvokeMainForm();        public LoginLoading()
            {
                InitializeComponent();
            }
          
            private void LoginLoading_Load(object sender, EventArgs e)
            {
                progressBarThread = new Thread(RunProgressBar);
                progressBarThread.Start();
                this.backgroundWorker.RunWorkerAsync();
            }
            
            private void RunProgressBar()
            {
                flag = true;
                while (flag)
                {
                    if (progressBarValue < 99)
                    {
                        progressBarValue++; 
                    }                this.progressBar.Value = progressBarValue;
                    Thread.Sleep(100);
                }
            }
            
            private void initMainForm()
            {
                if (mainForm == null)
                {
                    mainForm = new MainForm();
                }
            }
         
            private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                if (this.InvokeRequired)
                {
                    InvokeMainForm invoke = new InvokeMainForm(this.initMainForm);
                    this.Invoke(invoke);
                }            flag = false;
                this.progressBar.Value = 100;
                Thread.Sleep(100);
            }
          
            private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                this.Hide();
                Thread.Sleep(500);
                mainForm.Show();
            }
          }这个是我登录界面的代码,我的要求很简单,在登录界面上加个LABEL,显示我登录状态(类似Eclipse启动时那个进度框),但是上面的方法都试过了,无论是用委托给LABEL的TEXT赋值还是将LABEL传入主页面在每个方法前为其赋值都不行,各位有没有什么好办法?
      

  13.   

    首先使用BeginInvoke
    然后在自增的地方用Thread.Sleep(100)
    可否使用Timer控件
      

  14.   

    貌似还是不行,用TIMER给LABEL赋值还是会出异常