C# TreeViewについて質問させてください。
ノード(子ノード含む)を数万件以上登録する際に、効率の良い方法を教えて頂けないでしょうか?
実際のコードとは異なりますが、大まかに以下のような処理をメインスレッドで行っています。
class MyTreeNode : TreeNode{
void AddNode(){
BeginUpdate();
SuspendLayout();
foreach( var 親ノード情報 in 親ノード情報リスト ){
TreeNode parentNode = new TreeNode( 親ノード名 );
foreach( var 子ノード情報 in 子ノード情報リスト ){
TreeNode childNode = new TreeNode( 子ノード名);
parentNode.Nodes.Add( childNode );
}
this.Nodes.Add( parentNode );
}
ResumeLayout();
EndUpdate();
}
}
この方法ですと、かなり時間がかかってしまい、UIが固まったようになってしまいます。
(TreeViewに、子ノードの一斉展開機能が必要なので、親ノード展開時のイベントを拾って
子ノードを追加する方法は上記と同じく遅くなってしまうのではと思っていますがどうなんでしょうか?)
No.1ベストアンサー
- 回答日時:
今試せる環境がないので半分くらい無責任発言なんですが、一応案として、何かの参考になれば。
・効率が良くなるかもしれない方法
TreeNodeを配列化してAddRangeする(Addを使わず配列で渡す)
※配列はListではなくTreeNode[]でnew
・追加時間を短縮する方法
System.Threading.Tasks.Parallelを使って並列実行する
ぱっと見、1つの「親ノード情報」に対する子は予め決まってそうなので、「親ノード情報」単位で並列化が可能にみえます。ノード間で何かしら依存する場合はたぶん無理です。
・ノード追加処理を非同期化させるか、メッセージ処理をはさむ
UIが固まるのは、処理が重いからというより、ウインドウが長時間メッセージを処理できなくなるからです。
なので、たとえば何階層か展開する毎にメッセージ処理を挟めばUIが止まることはなくなります(処理中にウインドウが操作を受け付けるようになるので別の問題起き得ます)。
回答、ありがとうございます。
色々とバタバタして返信が遅くなってしまいました、すいません。
> TreeNodeを配列化してAddRangeする
この手法にて、約10万件追加されるときの時間が1秒以上改善されました。
大変たすかりました、ありがとうございます。
また、調査の結果、一番のネックになっているところが見つかりました。
(指摘頂いたコードを抜粋して質問させていただきましたが、そのあとの処理で親子ノード1個追加される度に、毎回Sortを実行していたので...)
試しに上記サンプルとSortを外して実行してみると、大きなストレスなく動作させることができました。
要望として、親ノードのソートはしたいですが、子ノードまでソートする必要はないと思われるので、ソート部分を自作して乗り切ろうと思います。
結局、質問した際のコードとは別のところが一番の原因で、大変申し訳ございません。
次はもう少し気をつけて質問します。
> System.Threading.Tasks.Parallelを使って並列実行する
> ノード追加処理を非同期化させるか、メッセージ処理をはさむ
上記2点についての案もありがとうございます。
私の今の力量では、期間内に両方検証し比較することができないので、後日時間があるときに、確認してみたいと思います。
(特にSystem.Threading.Tasks.Parallelは機能を確認してみると、できるとすごく便利そうです。)
複数の案とともに、処理改善もでき、一番の原因も判明いたしましたので、duke_kimuraさんをベストアンサーにさせていただき、この問題は解決済みにさせていただきたいと思います。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- XML マスターノード 1 2023/03/14 10:38
- その他(パソコン・スマホ・電化製品) 人間の長期記憶に関するモデルについて。 下記の内容をもとに、一番下の質問の具体例が思いつく方いたら具 1 2023/06/30 18:21
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
- その他(プログラミング・Web制作) google formsを使ったタスク依頼フォーム作成におけるご相談 1 2023/06/22 15:55
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- 楽天市場 楽天トラベルのクレジットカード情報 1 2023/06/20 23:19
- その他(データベース) Microsoft Accessについて 1 2022/06/06 16:20
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CPUの考え方を教えてください ...
-
SNMP リンクダウンとノードダ...
-
昔Winnyってありましたけど、あ...
-
同じタグ名の項目取得
-
ツリービューの使い方が・・・
-
各ノードの行数取得
-
C#でtreeviewの指定ノードを選...
-
XML文書の指定した属性値を持つ...
-
木のなぞり順をかえるプログラ...
-
C言語:文字列の並び替え
-
TreeVIewのノード名を編集する...
-
コンテキストメニュークリック...
-
2分探索木の高さを求めるプロ...
-
ツリービューのノードをダブル...
-
ルート要素ノードが2個ある場合?
-
2分木と双方向線形リストを同時...
-
あるノードリストに、特定の名...
-
最長経路探索
-
東芝のDynabookなのですがアン...
-
タグの有無の判定
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CPUの考え方を教えてください ...
-
昔Winnyってありましたけど、あ...
-
SNMP リンクダウンとノードダ...
-
ルート要素ノードが2個ある場合?
-
同じタグ名の項目取得
-
あるノードリストに、特定の名...
-
ノードとは
-
TreeView の初期表示について
-
ツリービューのノードをダブル...
-
ノード数とは?
-
コンテキストメニュークリック...
-
XML文書の指定した属性値を持つ...
-
C#でtreeviewの指定ノードを選...
-
複数のマックPCによる数値計算...
-
VB6.0ツリービューについて
-
TreeViewの再表示のちらつきを...
-
VB6.0でDOMを使用して...
-
vbsのDOMDocumentで要素のText...
-
TreeViewで複数ノードの選択は...
-
C# TreeView 効率良いノード追...
おすすめ情報