2011-01-05 18 views
0

私は映画、タイトル、長さ、最後にアクセスした時間を探してネットワークをクロールするアプリケーションを持っています。ネットワーク上には多くのコンピュータがあるので、これにはしばらく時間がかかりますし、リストビューをリアルタイムで更新したいと思います。私がこれまでに持っていたことは何もしていないが、それは全く役に立たない。Cでリアルタイムでリストビューの更新を行う方法

 private void PopulateListView() 
    { 
     this.listView1.SuspendLayout(); 

     listView1.Items.Clear(); 

     // go thru list of movies to add 
     foreach (string movie in listviewMovieList) 
     { 
      ListViewItem item1 = new ListViewItem(movie); 
      listView1.Items.AddRange(new ListViewItem[] { item1 }); 

     } 
     this.listView1.ResumeLayout();    
    } 

これは、メソッドProgressChanged私の背景労働者が呼び出されます:

 private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     string movie = (string)e.UserState;    

     if (movie != null) 
     { 
      listviewMovieList.Add(movie); 
      PopulateListView(); 

     } 

     this.progressBar1.Increment(e.ProgressPercentage);    
    } 
+0

このWPFまたはWinFormsですか?また、PopulateListView()が実際に実行時に呼び出されていることを確認できますか? –

+0

@GregそれはWinForms - SuspendLayout \ ResumeLayoutです。 –

+0

それがWinFormsの –

答えて

1

問題は十分に遅くないことです。 ReportProgress()を頻繁に呼び出しています。それはUIスレッドがどれくらい多くの作業を行うかによって異なりますが、1秒間に約百回実行し、UIスレッドはフリーズします。通常の仕事をやり直すことはもうありません。リストビューをペイントするのと同じです。あなたのコードは非常に高価です。リストビューをクリアして再投入するには、Windowsメッセージのが個必要です。

少なくとも一度に1つのムービーでそれを行い、バッチアップしてAddRange()メソッドを使用します。 50ミリ秒ごとに1つのコールが理想的です。人間はそれよりも速く読むことができません。 BeginInvoke()の代わりにInvoke()を使用してワーカースレッドをスローダウンします。 ListView.VirtualModeが役立ちます。

+0

で修正されました。ReportProgressメソッドの呼び出しを頻繁に停止し、Thread.Sleep(50)を追加して修正しました。ありがとうございました! –

0

を私は問題はWinフォームのUIコントロールにスレッド呼び出しを横断するかもしれないと思います。

Control.InvokeRequired Property

を見ては 製造方法は、制御 に呼び出したときに、呼び出し元が異なる スレッド上にあるため 呼び出し側がinvokeメソッドを呼び出す必要があるかどうかを示す値を取得しますコントロールよりも が作成されています。

Control.BeginInvoke Method (Delegate)は コントロールの基になるハンドルが が作成されたスレッド上で、非同期的に指定したデリゲート を実行します。

関連する問題