none
ウィンドウのハンドルを作成中にエラーが発生しました。 RRS feed

  • 質問

  • よろしくお願いします。

    VB.NET2008Expressにて

    Formアプリケーションを作成しておりますが

    何度もダイアログのShowとCloseを繰り返すと

    「ウィンドウのハンドルを作成中にエラーが発生しました。」

    が出てしまいます。

    ダイアログ側でMe.Closeとして、閉じさせていますが

    オブジェクトが解放されていないためでしょうか?

    Me.Disposeを入れる必要がある?

    上記のエラーは、リソース不足という情報を見ましたが

    リソースがどれくらい使われているなどの確認の方法はありませんでしょうか?

    よろしくお願いします。

    2014年8月21日 0:32

回答

すべての返信

  • とりあえず情報が足りませんので、以下のような感じのやり取になるかと思います。一度、ご覧下さい。

    ウィンドウのハンドルを作成中にエラーが発生しました。
    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=32093&forum=7


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年8月21日 1:26
    モデレータ
  • 回答ありがとうございます。

    上記、リンクも確認しましたが。。。

    私も、まったく、ソースもどの部分を公開すればよろしいのか

    分からなくて困っております。

    一応、分かってると言いますか。

    確認したい項目として、ダイアログを作成した後に、今は、Closeで閉じています。

    ダイアログShowの場合は、Closeで閉じて。

    また、再度、Showすると、前のインスタンス?を使用してオープンするって

    ことを聞いておりますが、どうも、そうなっておらず、毎回、インスタンス化されて

    ハンドルが増え続けてエラーとなっている気がします。

    そこで、ハンドルの確認はタスクマネージャで確認でよろしいですよね。

    その際のハンドルの制限っていくつなのかという情報はないのでしょうか?

    分かりにくい文章で申し訳ありません。

    2014年8月21日 9:52
  • モーダル(ShowDialog()メソッドで表示)ではなくモードレス(Show()メソッドで表示)ですか?

    ちなみに本当にClose()メソッドが呼び出されていますか? Windows FormsのSystem.Windows.Forms.Formでも、WPFのSystem.Windows.Windowでも、モードレスウィンドウで一度Close()メソッドを呼び出すと再びShow()メソッドを呼び出せないはずですが……

    Form.Close メソッド  (System.Windows.Forms)

    GDIオブジェクトハンドルの上限は10,000です。

    Windows の限界に挑む: USER オブジェクトと GDI オブジェクト – 第 2 部

    タスク マネージャーの他にProcess Explorerでも確認できます。

    あとフォーラム系では半角カナは使わないようにしましょう。

    2014年8月21日 11:30
  • 回答ありがとうございます。

    >あとフォーラム系では半角カナは使わないようにしましょう。

    了解しました。ご指摘ありがとうございます。

    でも、なぜですか?化けたりするのでしょうか?

    さて、本題ですが

    Dim objForm As Form = New MainForm
    objForm.ShowDialog()

    としています。

    ですので、モーダルです。

    で、これだと、MainForm側で、Me.Closeで終了させてますが

    この終了だと、インスタンスは残ったままですか?

    すいません。初心者なので、表現があっているかわかりませんが。。

    もし、インスタンスが残ったままだと、まだ、再度開くときに

    Dim objForm As Form = New MainFormをすると

    またインスタンスが作成されて、ハンドルがいっぱいになりますか?

    ただいま、実験中ですが。

    どうなのでしょうか?

    よろしくお願いします。

    2014年8月21日 12:21
  • 連続投稿で申し訳ありません。

    ふと気づいたのですが、2台のPCで本ソフトを確認しておりますが

    1台は「ウィンドウのハンドルを作成中にエラーが発生しました。」という結果ですが。

    もう1台は「メモリー不足」という結果になります。

    ハンドルが増えてリソース不足で1台はとまり

    もう1台はハンドルが増えてリソース不足に引っかかる前にメモリーが少ないために

    メモリー不足で止まるっていうストーリーが成り立ちますか?

    2014年8月21日 12:45
  • あ~、ShowDialogでしたか。一瞬、頭をよぎったのですが、Showと書かれていたので違うのかと思いました。ShowDialogの場合、適切にDisposeを呼び出す必要があります。

    Form.ShowDialog メソッド
    http://msdn.microsoft.com/ja-jp/library/c7ykbedk(v=vs.110).aspx

    もしくは、usingを使います。

    プロパティでフォーム間受渡し(Disposeで破棄?)
    http://oshiete.goo.ne.jp/qa/3550553.html


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク t_osk 2015年2月10日 9:17
    2014年8月21日 12:48
    モデレータ
  • 半角カナを使わない、というのはWebマナーと見た目の美しさ(統一感)の2点でしょうか。

    できるところから始めるウェブアクセシビリティ対策 - 半角カタカナや機種依存文字を使用しない - 東海総合通信局

    Unicodeが普及してきているとはいえ、半角カナやギリシャ数字、丸囲み数字などはできるかぎり避けたほうがよいかと思われます。統一感という観点ではそもそもMSDNフォーラムで使われているMeiryo UIフォントのデザインもどうかとは思うのですが……

    本題に戻りますが、ShowDialog()メソッドで表示するモーダルダイアログの場合、ShowDialog()メソッドが終了した時点ですでにウィンドウは非表示の状態になっています。が、Formオブジェクトが内部で管理しているウィンドウリソースハンドルはまだ生きたままです。これはプログラマーが明示的にIDisposable.Dispose()を呼び出してリソースを破棄しなければなりません。まずは下記の解説や例をきちんと読んでみてください。

    Form.ShowDialog メソッド  (System.Windows.Forms)

    IDisposableを適切に実装していれば、誰からも参照されなくなったオブジェクトの場合、ガベージコレクターによってオブジェクトのファイナライザーが呼び出されたタイミングでリソースは破棄されますが、それがいつになるのかはまったく予測ができないため、IDisposableを実装したクラスのオブジェクトに関してはGC任せにせずDispose()を呼び出してリソースを明示的に破棄するのがマナーです。

    他にもUsingステートメントを使って、C++のデストラクタのようにスコープを抜けた時点でIDisposable.Dispose()が自動的に呼び出されるようにする方法もあります。フィールドを使ってインスタンスを保存したりせず、ローカル変数を使って一時的にオブジェクトを生成するだけであればUsingのほうが簡単かつ確実です。

    Using objForm As New MainForm
        objForm.ShowDialog()
    End Using

    あてずっぽうに勘でコードを書くのではなく、まずは上記のような解説や例をきちんと読んだ上でコーディングする「写経」を心がけましょう。プログラミングも料理・スポーツ・芸術・囲碁将棋同様、定石や定型を学ぶのが大切です。

    • 編集済み sygh 2014年8月21日 16:13
    2014年8月21日 12:55