- - PR -
Formに配置できるコントロール数には限界がある?
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-02-20 11:55
お世話になります。
VB.NET 2003 で開発をしていて気づいたのですが、Formに配置できるコントロールの数には上限が定まっているのでしょうか? 例えば、何も配置していないFormのロードイベントで以下のコードを実行してみました。 ------------------------------ Dim ctrl As Control For i As Integer = 0 To 65535 ctrl = New TextBox Me.Controls.Add(ctrl) Debug.WriteLine(i) Next ------------------------------ すると必ず9983個目でエラーが起こるのです。 エラー内容は『ウィンドウのハンドルを作成中にエラーが発生しました。』というものです。 コントロールはTextBoxでもLabelでもButtonでも同じ結果のようです。 また、あらかじめForm上にTextBoxを1つ配置しておくと、上記のコードは9982個目でエラーが起こるようになりました。 Formに9983個以上のコントロールを貼り付けるのは無理なのでしょうか? 解決法をご存知の方がいらっしゃればご教授いただけるでしょうか? ちなみに、環境は WinXP SP2 + VB.NET 2003 です。 | ||||
|
投稿日時: 2006-02-20 11:59
メモリ不足なのかどうかを見たいので、スタックトレースをください。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||
|
投稿日時: 2006-02-20 13:04
明確な上限値が定められているわけではありませんが、上限は存在します。 理由は簡単です。 コントロールを生成・維持するためにはそれなりの資源が必要からです。 仮に、あるコントロールが 100MB の実メモリを必要とする作りであるなら、32bit 環境では 10 数個生成するのがやっとでしょう。 実際にはそんな極端なコントロールは非常に珍しいですが、コントロールの生成・維持にはOSからプロセスに割り当てられた資源がどうしても必要で、歴史的な経緯もあってそれは有限量しか存在しません。 そういった資源を使い切れば、コントロールの生成にしっぱいすることはあるでしょう。 それ以前の問題として、数千個ものコントロールを必要とするようなUIは設計を見直すべき物と思います。 | ||||
|
投稿日時: 2006-02-20 13:16
限界があるというのは明白なのだろうけども、毎回全く同じ個数となると興味深いですね。どこかで上限値でもきまっているのかな、と思ってしまいますね。
もう一個フォームを作って同時に作ってみたらどうなるでしょうか。半分になるのかな?それともどちらも9983個かな? _________________ 囚人のジレンマな日々 | ||||
|
投稿日時: 2006-02-20 13:30
VB.NET Windows Forms 上のコントロールの制限についてのようにForm側での制限はありません。
なので、ぶっちゃけOS側の制限です。じゃんぬねっとさんが示すようなメモリ不足の可能性もありますが、一番の問題は恐らくデスクトップアプリケーションヒープです。 もともとuser32とかの構造上そんなにたくさんのコントロールを保持できるような仕組みになっていません。Control自体が重く、共有されるリソースです。 ちなみに「解決策として上限をあげればいい」ということでもなく、不用意に増やすとシステムに悪影響を与える可能性もあります。 結局のところ、コントロールはたくさん作らないでください。 # たしかタスクマネージャあたりで他のアプリがどれだけ使っているか # 確認できるので見てみるといいかも。 | ||||
|
投稿日時: 2006-02-20 13:37
ところで、かにかにさんは知的好奇心で知りたいのでしょうか?それとも、何とかして1万個を超えるようなコントロールをもったFormを作りたいということなのでしょうか?
後者でしたら、明らかにFormの設計がおかしいので見直しをしたほうがいいですね。 # なぜ9983個なのかは、私も興味があります | ||||
|
投稿日時: 2006-02-20 13:40
返信ありがとうございます。
じゃんぬねっと 様 すいません。スタックトレースという言葉は聞いたことがあり意味もなんとなく分かるのですが、VB.NETのスタックトレースの取り方というのが分からずググっていました。...が、やり方が依然として分かりません。 もし、可能でしたらスタックトレースの取り方を教えていただけるでしょうか? 渋木宏明(ひどり) 様 分かりやすい解説、ありがとうございます。けっこう納得な話です。 ちなみに、今回分かりやすく説明するためにまっさらなFormにコントロールを1万個近く配置するコードを書きましたが、実際は少し違うのです。 グリッドのようなものに明細を数百行表示したいのですが、それぞれ1明細の中にさらにサブ明細を数十行持っているのです。また、そのグリッドでデータの編集も行い、検索ボタンなども付いています。よってDataGridを使用するのをあきらめ、明細とサブ明細それぞれの1行分のUserControlを作り、それをPanelに貼り付けて擬似グリッドとして使用しようという考えでした。明細にはコントロールが約20個、サブ明細には約5個のTextBoxやLabelなどが張り付いています。 ところがサブ明細をそれぞれ10行程度持つ明細を7〜80行Panelに配置すると、例のエラーメッセージが表示されて異常終了してしまうのです。 よってこの質問をさせてもらったという訳です。 | ||||
|
投稿日時: 2006-02-20 13:46
返答を書いている間に、他の方からも返答いただいていたみたいですね。
ya 様 「デスクトップアプリケーションヒープ」はというものは初めて知りました。 リンク先の@ITのWindowsTIPSを読んで理解しました。わざわざ調べていただいてありがとうございます。 どうやら、私の設計を変更しないといけないようですね。 まいるどきゃっと 様 理由は行き違いになった1つ前の私の発言の通りです (^^) |