- PR -

Formに配置できるコントロール数には限界がある?

投稿者投稿内容
かにかに
会議室デビュー日: 2005/03/23
投稿数: 18
投稿日時: 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 です。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-20 11:59
引用:

かにかにさんの書き込み (2006-02-20 11:55) より:

エラー内容は『ウィンドウのハンドルを作成中にエラーが発生しました。』というものです。


メモリ不足なのかどうかを見たいので、スタックトレースをください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-02-20 13:04
引用:

VB.NET 2003 で開発をしていて気づいたのですが、Formに配置できるコントロールの数には上限が定まっているのでしょうか?



明確な上限値が定められているわけではありませんが、上限は存在します。

理由は簡単です。
コントロールを生成・維持するためにはそれなりの資源が必要からです。

仮に、あるコントロールが 100MB の実メモリを必要とする作りであるなら、32bit 環境では 10 数個生成するのがやっとでしょう。

実際にはそんな極端なコントロールは非常に珍しいですが、コントロールの生成・維持にはOSからプロセスに割り当てられた資源がどうしても必要で、歴史的な経緯もあってそれは有限量しか存在しません。

そういった資源を使い切れば、コントロールの生成にしっぱいすることはあるでしょう。

それ以前の問題として、数千個ものコントロールを必要とするようなUIは設計を見直すべき物と思います。

囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-02-20 13:16
限界があるというのは明白なのだろうけども、毎回全く同じ個数となると興味深いですね。どこかで上限値でもきまっているのかな、と思ってしまいますね。
もう一個フォームを作って同時に作ってみたらどうなるでしょうか。半分になるのかな?それともどちらも9983個かな?
_________________
囚人のジレンマな日々
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2006-02-20 13:30
VB.NET Windows Forms 上のコントロールの制限についてのようにForm側での制限はありません。
なので、ぶっちゃけOS側の制限です。じゃんぬねっとさんが示すようなメモリ不足の可能性もありますが、一番の問題は恐らくデスクトップアプリケーションヒープです。

もともとuser32とかの構造上そんなにたくさんのコントロールを保持できるような仕組みになっていません。Control自体が重く、共有されるリソースです。
ちなみに「解決策として上限をあげればいい」ということでもなく、不用意に増やすとシステムに悪影響を与える可能性もあります。
結局のところ、コントロールはたくさん作らないでください。

# たしかタスクマネージャあたりで他のアプリがどれだけ使っているか
# 確認できるので見てみるといいかも。
まいるどきゃっと
大ベテラン
会議室デビュー日: 2004/08/12
投稿数: 135
お住まい・勤務地: 群馬
投稿日時: 2006-02-20 13:37
ところで、かにかにさんは知的好奇心で知りたいのでしょうか?それとも、何とかして1万個を超えるようなコントロールをもったFormを作りたいということなのでしょうか?

後者でしたら、明らかにFormの設計がおかしいので見直しをしたほうがいいですね。

# なぜ9983個なのかは、私も興味があります
かにかに
会議室デビュー日: 2005/03/23
投稿数: 18
投稿日時: 2006-02-20 13:40
返信ありがとうございます。

じゃんぬねっと 様
すいません。スタックトレースという言葉は聞いたことがあり意味もなんとなく分かるのですが、VB.NETのスタックトレースの取り方というのが分からずググっていました。...が、やり方が依然として分かりません。
もし、可能でしたらスタックトレースの取り方を教えていただけるでしょうか?


渋木宏明(ひどり) 様
分かりやすい解説、ありがとうございます。けっこう納得な話です。

ちなみに、今回分かりやすく説明するためにまっさらなFormにコントロールを1万個近く配置するコードを書きましたが、実際は少し違うのです。
グリッドのようなものに明細を数百行表示したいのですが、それぞれ1明細の中にさらにサブ明細を数十行持っているのです。また、そのグリッドでデータの編集も行い、検索ボタンなども付いています。よってDataGridを使用するのをあきらめ、明細とサブ明細それぞれの1行分のUserControlを作り、それをPanelに貼り付けて擬似グリッドとして使用しようという考えでした。明細にはコントロールが約20個、サブ明細には約5個のTextBoxやLabelなどが張り付いています。
ところがサブ明細をそれぞれ10行程度持つ明細を7〜80行Panelに配置すると、例のエラーメッセージが表示されて異常終了してしまうのです。
よってこの質問をさせてもらったという訳です。
かにかに
会議室デビュー日: 2005/03/23
投稿数: 18
投稿日時: 2006-02-20 13:46
返答を書いている間に、他の方からも返答いただいていたみたいですね。

ya 様
「デスクトップアプリケーションヒープ」はというものは初めて知りました。
リンク先の@ITのWindowsTIPSを読んで理解しました。わざわざ調べていただいてありがとうございます。
どうやら、私の設計を変更しないといけないようですね。


まいるどきゃっと 様
理由は行き違いになった1つ前の私の発言の通りです (^^)

スキルアップ/キャリアアップ(JOB@IT)