解决方案 »

  1.   

    你应该把耗时的操作放在线程中,而不是Invoke中,Invoke只放和UI刷新有关的操作。
      

  2.   

    版主你好,你的意思是即使在backgroundWorker中,使用了Invoke也就不算是在后台线程中了?
    那我应该怎么操作?
      

  3.   

    另外,好像backgroundWorker_DoWork是算是线程中执行费时的操作吧?那要在什么时候怎么样把数据列到ListView中去呢?迷糊了
      

  4.   

    backgroundWorker_DoWork是一个线程,但是你在使用Invoke的时候,是将Invoke中代码交给UI主线程来执行,所以会卡,所以你要将费时跟UI不想关的代码写在Invoke以外的地方,而跟UI相关的写在Invoke中(跟UI相关的操作要交给UI主线程来操作)
      

  5.   

    backgroundWorker_DoWork是一个线程,但是你在使用Invoke的时候,是将Invoke中代码交给UI主线程来执行,所以会卡,所以你要将费时跟UI不想关的代码写在Invoke以外的地方,而跟UI相关的写在Invoke中(跟UI相关的操作要交给UI主线程来操作)您好,backgroundWorker_DoWork是不是只是查询数据并储存到定义的数组中,然后在外部将数组中的数据再次填到ListView中?不太懂,能不能帮我写一下你们的习惯格式?
      

  6.   

    backgroundWorker_DoWork是一个线程,但是你在使用Invoke的时候,是将Invoke中代码交给UI主线程来执行,所以会卡,所以你要将费时跟UI不想关的代码写在Invoke以外的地方,而跟UI相关的写在Invoke中(跟UI相关的操作要交给UI主线程来操作)您好,backgroundWorker_DoWork是不是只是查询数据并储存到定义的数组中,然后在外部将数组中的数据再次填到ListView中?不太懂,能不能帮我写一下你们的习惯格式?
    并不是你所说的这样,backgroundWorker能够完成所有的工作: private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                //...查询数据库的过程
                //...很多查询记录,并将记录列出到表中
                this.Invoke((MethodInvoker)delegate
                {
                    this.listView.BeginUpdate();
                    this.listView.Items.Clear();
                    //循环添加记录:listView.Items.Add()
                    this.listView.EndUpdate();
                });
            }
      

  7.   

    如果查到的数据非常多,比如我查到要列到ListView中的行数为近两千条,是不是会卡?另外你说到“//...很多查询记录,并将记录列出到表中”这个列出到表中是指?
      

  8.   

    backgroundWorker_DoWork 就是 backgroundWorker_DoWork  画蛇添足!
      

  9.   

    不太明白你什么意思?
    是不是想说backgroundWorker_DoWork只是做后台的事?窗体控件怎么办?
      

  10.   

    窗体控件直接就可以操作  ListBox 直接操作
    只需要在构造函数中(不确定了)中告诉他支持异步操作
      

  11.   

    窗体控件直接就可以操作  ListBox 直接操作
    只需要在构造函数中(不确定了)中告诉他支持异步操作
    构造函数中家System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
      

  12.   

    窗体控件直接就可以操作  ListBox 直接操作
    只需要在构造函数中(不确定了)中告诉他支持异步操作
    构造函数中家System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
    好像有人说过这样操作不太好……
      

  13.   

    不是告诉你了么,把耗时的操作放在Invoke之外。
      

  14.   

    你应该在DoWork读取数据,例如从数据库读取,然后将数据返回给e.Result,在Finished事件读取e.Result得到数据,再写入界面。
    假如嫌写入到界面很慢,也可以在ReportProgress事件一笔一笔的写入到ListView,这样就不会卡住界面了。
      

  15.   

    汗,那个不是你原来代码的部分么,我的意思是,那部分代码移动出去,到invoke外边
      

  16.   

    版主没有看到我7楼写的情况,因为数据多,其实将数据加载到ListView里面也是一个卡的过程。
    另外Rail100 大哥,怎么将Work过程取的数据传送到Progress中,并可以取值,是不是也是查到一个,ListView加载一个,这样ListView会闪跳
      

  17.   

    backgroundWorker_DoWork是一个线程,但是你在使用Invoke的时候,是将Invoke中代码交给UI主线程来执行,所以会卡,所以你要将费时跟UI不想关的代码写在Invoke以外的地方,而跟UI相关的写在Invoke中(跟UI相关的操作要交给UI主线程来操作)您好,backgroundWorker_DoWork是不是只是查询数据并储存到定义的数组中,然后在外部将数组中的数据再次填到ListView中?不太懂,能不能帮我写一下你们的习惯格式?
    并不是你所说的这样,backgroundWorker能够完成所有的工作: private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                //...查询数据库的过程
                //...很多查询记录,并将记录列出到表中
                this.Invoke((MethodInvoker)delegate
                {
                    this.listView.BeginUpdate();
                    this.listView.Items.Clear();
                    //循环添加记录:listView.Items.Add()
                    this.listView.EndUpdate();
                });
            }
    你这段代码我不清楚的是因为查询过程本来就是一个循环过程,相当于第一个循环结束后,查询记录后数据保存在哪里?是数组里?再次循环添加记录到ListView里?请指教
      

  18.   

    backgroundWorker_DoWork是一个线程,但是你在使用Invoke的时候,是将Invoke中代码交给UI主线程来执行,所以会卡,所以你要将费时跟UI不想关的代码写在Invoke以外的地方,而跟UI相关的写在Invoke中(跟UI相关的操作要交给UI主线程来操作)您好,backgroundWorker_DoWork是不是只是查询数据并储存到定义的数组中,然后在外部将数组中的数据再次填到ListView中?不太懂,能不能帮我写一下你们的习惯格式?
    并不是你所说的这样,backgroundWorker能够完成所有的工作: private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                //...查询数据库的过程
                //...很多查询记录,并将记录列出到表中
                this.Invoke((MethodInvoker)delegate
                {
                    this.listView.BeginUpdate();
                    this.listView.Items.Clear();
                    //循环添加记录:listView.Items.Add()
                    this.listView.EndUpdate();
                });
            }
    你这段代码我不清楚的是因为查询过程本来就是一个循环过程,相当于第一个循环结束后,查询记录后数据保存在哪里?是数组里?再次循环添加记录到ListView里?请指教
    在ListView添加之前都是数据的组织过程,你想怎么组织就怎么组织,你只可以直接new List<xx>的类来存储你的数据,
    添加过程你可以直接在Invoke里面进行添加~
      

  19.   

    读100条再invoke一次,别每次都invoke就行了
      

  20.   

    明白了你的意思,谢谢。这种操作不懂怎么弄,与18楼的意思差不多么?定义一List<>,然后判断List<>数量到了100循环加到ListView,再清空List<>继续循环查询?
      

  21.   

    我不确定你的是Winform的,还是WPF的程序,在WPF中直接将集合赋值给ItemsSource就可以了,而在Winform中好像是DataSource还是什么的,这个我不太清楚~
      

  22.   

    不知道你用没有用数据绑定哦,你是查询数据出来,直接加到Listview里面,一条一条加吗?
    如果是这样,建议你先运用数据绑定,这样可以把UI刷新和修改数据分开来
    然后,只要把修改数据内容(包括查询数据)的操作放在非UI线程就好了,就是在你的DoWork里面,只要不操作UI,就不要用Invoke。
    如果,还是嫌整个添加数据的过程太慢,就加进度条提示用户嘛。
      

  23.   

    刚试了下,你的是Winform,从MSDN理解来看,你最初的操作就可以,使用BeginUpdate方法和EndUpdate方法,List集合在new的时候可以传入capacity容量的参数,你可以直接创建一个大容量的list,不用每次都调用clear,可以一次添加完成以后