大概流程:点击按钮,逐一开启新的子线程(等待前一个子线程完成后再开启后面的子线程),子线程中代码使用委托的方式读取UI中listview的数据,代码如下:     public void button5_Click(object sender, EventArgs e)
        {            for (int index = 0; index < Convert.ToInt32(textBox33.Text); index++)
            {
                th[index] =new Thread(new ThreadStart(delegate() { StartScript(index); }));
                th[index].IsBackground = true;
                MessageBox.Show("222");
                th[index].Start();
                th[index].Join();
            }
         }  public void StartScript(int index)
        {
                    KaiShiClass KaiShiClass = new KaiShiClass();
                    KaiShiClass.KaiShiiMain(this, index);
        }
KaiShiClass这个类里面有读取UI界面的listview数据的代码(已使用委托的方式读取)。
问题:使用了 th[index].Join();能逐一开线程,但是读取数据时由于UI线程被阻塞,导致不能读取数据而界面整个卡死。
      如果不用th[index].Join();线程又不能逐一开启。所以请教,要达到逐一开启线程而又不会使界面卡死的解决方案,相信这个问题有很多人遇到过,遇到过的前辈请赐教啊。查了大量资料,实在没办法才来发帖。多线程UI卡死

解决方案 »

  1.   

    在主线程中调用Join(),也就是在主线程中加入了th线程的代码,必须让th线程执行完毕之后,主线程才能正常执行。
    这样的话,UI肯定会卡了.
      

  2.   


    一个线程就执行了读取listview中索引的数据.执行完了,你的线程就不在执行了.
    用一个线程就可以了吧.
    在StartScript这个方法里面循环算了.
      

  3.   


    一个线程就执行了读取listview中索引的数据.执行完了,你的线程就不在执行了.
    用一个线程就可以了吧.
    在StartScript这个方法里面循环算了.
    开一个线程读取UI是一样的效果吧,UI还卡着呢,如果在StartScript里循环,我得到的数据就会不正常了
      

  4.   

    想到使用AutoResetEvent,但是waitone 和set都只能用知道线程名,不知道怎么用数组来控制
      

  5.   

    比如 th[index].set()             th[index]无法声明为AutoResetEvent     有什么方法吗?
      

  6.   


     button5_Click里面的代码块写成一个函数 ,用一个线程来调用。这样th[index].Join();就不会阻塞UI线程了,而是阻塞这个调用线程,这样界面就不会卡死 了。
      

  7.   

    多开一个线程执行循环的方法, new AutoResetEvent 做阻塞,不要用Join这个在2.0之后建议不在使用。    
      

  8.   

    不要指望用一个循环来实现。
    最简单的办法是用BackgroundWorker,在DoWork事件里调用StartScript,而在RunWorkerCompleted事件里检查index是否达到了预期的值,如果还没有,再次RunWorkAsync,否则就结束。当然,还需要一些额外的信息来保存环境参数。
    不过我有一点不太明白,为什么非得设计成这个样子,既然线程必须是顺序执行的,为什么不能在一个线程里完成所有的工作呢?
      

  9.   

    线程里面最好还是不要直接操作UI,应该使用 Invoke 方式。private delegate void RefreshSmallDelegate(bool isPack);
            //需要执行的更新操作
            private void RefreshSmallProcess(bool isPack)
            {
                try
                {
                    //界面操作
                }
                catch(Exception ex)
                {
                    
                }
            }        /// <summary>
            /// 界面刷新-单品
            /// </summary>
            private void RefreshSmallStatus(bool isPack)
            {
                Invoke(new RefreshSmallDelegate(RefreshSmallProcess), new object[] { isPack });
            }
      

  10.   


    你连Sleep都没有,不死才怪。 Sleep,DoEvent
      

  11.   


    你连Sleep都没有,不死才怪。 Sleep,DoEvent  正解