みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

Me.Close()


Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。
    • good
    • 4
この回答へのお礼

ご回答を賜り、ありがとうございました。そして、お返事が遅くなり、申し訳ございませんでした。

インスタンスの破棄の件につきましては、理解できました。とても勉強になりました。ありがとうございます。

フォームをCloseしたのに、タイマーイベントが実行され続ける意味も分かりました。そのフォームのクラスのインスタンスが残ってたんですね。このようにインスタンスを明示的に破棄する必要がある場合は、おっしゃるとおり、両方併記しなければならない件、よく理解できました。

どうしてもインスタンスを破棄したい場合は、併記をするようにしましたところ、問題は起こっていません。

丁寧なご説明をいただき、ありがとうございました! とても勉強になりました。心より感謝申し上げます。

お礼日時:2009/05/23 03:54

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDataGridViewで指定したセルの値を取得

こんにちは。

VB2008のDataGridViewで指定したセルの値を取得をする方法がわかりません。
どなたか教えてください。

Aベストアンサー

こんばんは.

 Dim Data As String
 Data = Me.DataGridView(0, 2).Value
 MsgBox(Data)

みたいな感じで取れないですかね???

QDispose()は、どんな時に使うのですか?

VB2005を使っていますがなかなか覚えられません。
Dispose()は、どんな時に使うのですか?
その必要性、背景から知りたいです。

Aベストアンサー

Disposeというか,System.IDisposableインターフェイスについてになります。

まず,System.IDisposableを調べると,クラスのsummaryに,
「割り当てられたアンマネージ リソースを解放するメソッドを定義します。」
とあります。
MSDN: IDisposable インターフェイス (System)
http://msdn.microsoft.com/ja-jp/library/system.idisposable(VS.80).aspx
元々は,.NET Frameworkが管理しないリソース,つまりはメモリ以外のリソースを解放する共通のインターフェイスとして用意されました。
つまり,リソースAではCloseを,リソースBではDiscardを,etc. のようなことが無いように,IDisposable.Disposeに一本化したものです。
C#では当初(1.0)から,VBでは8.0 (2005)から,Usingステートメントが追加されていますが,これはIDisposableによるリソースの管理を簡易にするための物です。

ただし,上記は.NET Framework 2.0のMSDNです。
故意に2.0を持ち出したのは意味がありまして,3.5になると以下のように変わっています。
「割り当てられたリソースを解放するメソッドを定義します。」
MSDN: IDisposable インターフェイス (System)
http://msdn.microsoft.com/ja-jp/library/system.idisposable(VS.90).aspx
つまり,元々はアンマネージリソースを想定していたが,現在ではマネージリソースでも使うことが存在しているようです (例示ができないので曖昧)。


さて,IDisposableの使い方についてです。

[呼び出し側として使う場合]
こちらの方が当然多いわけですが,
・自分が管理責任を持っているオブジェクト
基本的にはNewしたオブジェクトですが,System.Net.WebRequest.GetReseponseのように,管理がまわってくるオブジェクトも存在します。
これに関しては,理由がない限り使い終わったら速やかにIDisposable.Disposeを呼び出すべきです。
・自分が管理責任を持っていないオブジェクト
System.Windows.Forms.Control.Paintイベントのe.Graphicsなどが該当します。
これに関しては,IDisposable.Disposeを呼び出してはいけません。

[IDisposableを実装する場合]
実はこれも結構起きたりします。
・自分がアンマネージリソースを扱っている場合
そのリソースを解放する必要があるのであれば,IDisposableを実装する必要があります。
MSDN: アンマネージ リソースをクリーンアップするための Finalize および Dispose の実装
http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx
・フィールドがIDisposableを実装している場合
これは,呼び出し側として使う場合の管理責任を持つかどうかに依存します。
持つならば,IDisposableを実装し,IDisposable.Dispose内でフィールドのIDisposable.Disposeを呼び出す必要があります。


参考になりそうな資料ですが,
MSDNマガジン: CLR 徹底解剖: IDisposable について
http://msdn.microsoft.com/ja-jp/magazine/cc163392.aspx
GDNJ: GotDotNet Japan 掲示板 / スレッド: IDisposable/Dispose/using に関して
http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-4718.htm
などがあります。後者は2003年,つまりは.NET Frameworkの初期の頃の議論ですが,結構重要な議論だと思います。
# ログの破損が惜しいところです。

Disposeというか,System.IDisposableインターフェイスについてになります。

まず,System.IDisposableを調べると,クラスのsummaryに,
「割り当てられたアンマネージ リソースを解放するメソッドを定義します。」
とあります。
MSDN: IDisposable インターフェイス (System)
http://msdn.microsoft.com/ja-jp/library/system.idisposable(VS.80).aspx
元々は,.NET Frameworkが管理しないリソース,つまりはメモリ以外のリソースを解放する共通のインターフェイスとして用意されました。
つまり,リソ...続きを読む

QForm間の値の渡し方

1つのForm上のコマンドボタンで別のFormを表示、そこで変数に値を入れ、そのFormを閉じ、元のFormでその変数を使いたいのですが、どうもうまくいきません。
実施したやり方は、一方のFormの宣言領域で、”Public abc As String”を宣言、両方のFormの(変数に値を入れた方と変数を使う方の)プロシージャーの宣言では引数として(abc As String)と記述しました。
因みに、両プロシージャーともイベントプロシージャーです。何か基本的なことができていないのだとは思いますが、どなたか教えていただけませんか?よろしくお願いします。

Aベストアンサー

すでに何件か回答があがっていますので、少し変わった方法をご参考までに。

あまり使われませんが、Formにはtagというプロパティがあります。
これは「文字列形式であれば何でも格納できる」という、上手く使えば便利なプロパティです。

FormAからFormBを呼び出し、FormBで変更した値をFormA.tagにセットします。
ここでFormBをUnloadしてもFormA.tagの値は影響を受けないので自由に使えます。

複数の値を呼び出し元に戻してやる場合に、区切り文字(カンマなど)で連結した文字列をtagに格納し、呼び出し元で区切り文字でsplitして、複数の値を受け渡すという手法をよく使っています。

QVB.NETのコンボボックスについて

VB6からVB.NETでプログラミングを始めました。
コンボボックスのクリアの仕方や設定の仕方、また
取り出し方等を教えて下さい。

色々とヘルプも見てみたのですが、よく解りません。
宜しくお願い致します。

Aベストアンサー

クリアだけだと思ってました。
追記します。

Itemを操作します


'登録
For i = 1 To 10
  Me.ComboBox1.Items.Add(i.ToString)
Next

'取得
For i = 0 To Me.ComboBox1.Items.Count - 1
  MsgBox(Me.ComboBox1.Items(i).ToString)
Next

'完全クリア
Me.ComboBox1.Items.Clear()

部分クリア
Me.ComboBox1.Items.RemoveAt(Index値)

QC# インスタンスの破棄

C#でインスタンスの破棄を明示的に行いたいのですが、
実際の開発現場では、どのように行っているのでしょうか?

自分で調べると「ガベージコレクタ」が暗黙的に行っているようですが明示的には行わないのが普通なのでしょうか?
もしくは、「Dispose」を使用して明示的に行うのが普通なのでしょうか?

実際に開発されている方からすると簡単な事かもしれませんが教えて頂けると助かります。

以上ですが、よろしくお願いいたします。

Aベストアンサー

結論から言うと、どちらでも良いです。
できれば生成から破棄まで考えて開発できると良いですね。

ガベージコレクションが実行されることで自動開放されますから、
一切.close()や.dispose()を使わなかったとしてもプログラムが
不正終了してしまう事はほとんどありません。

実際の開発では使わなくなったものを使わなくなった時点で
明示的に破棄することが多いです。正確には明示的に破棄するもの、
明示的に破棄しないもの、の2種類に分類しています。

例えばファイルを読み書きするストリーム系のオブジェクトや
データベースとのコネクションなどです。これは開発会社や
開発チーム、案件によって若干違っていて、徹底するところや
適当なところもあります。個人的には徹底したい派ですが。。。

ガベージコレクションが発生するとプログラムの実行動作が
遅くなり、また瞬間的に大きな負担がかかることがあります。
そのため全てをガベージコレクタに任せるのではなく、
明示的に開放できるもの、メモリを大量に消費するものは
その都度、適切に開放していくことで処理効率が良くなります。

プログラミング関連の調べ物で、サンプルソース等を見ることが
あるかと思います。この時サンプルで明示的に開放していたら、
それは明示的に開放したほうが良いもの、と思いましょう。
これだけでもステップアップになりますね。

結論から言うと、どちらでも良いです。
できれば生成から破棄まで考えて開発できると良いですね。

ガベージコレクションが実行されることで自動開放されますから、
一切.close()や.dispose()を使わなかったとしてもプログラムが
不正終了してしまう事はほとんどありません。

実際の開発では使わなくなったものを使わなくなった時点で
明示的に破棄することが多いです。正確には明示的に破棄するもの、
明示的に破棄しないもの、の2種類に分類しています。

例えばファイルを読み書きするストリーム...続きを読む

QVB.NETのDataGridで、選択行の特定の列の内容を取得したい

タイトルにあるとおり、DataGridを使用している場合、実行時に選択された行の特定の列の内容を取得するにはどのようにすればよいのでしょうか?

DataGridは複雑で、まだよくわかっていません。
よろしくお願いします。

Aベストアンサー

選択している行番号は、dataGrid1.CurrentRowIndexでわかります。
行、列を指定して各セルにアクセスするには、
dataGrid1(行番号,列番号)でいいので
dataGrid1(dataGrid1.CurrentRowIndex,列番号)
で選択されている行の特定の列の内容を取得できます。
註:番号は、0始まり

QVB.NETで他のプロジェクトで作成したフォームを使う方法

こんにちは。
VB.NETのプロジェクトがぐちゃぐちゃで参照設定とかいろんなの呼んでしまっているので、新しく作成しなおしたいのですが、
新しいプロジェクトでプロジェクトを作成し、前のプロジェクトで必要なファイル(.vb、RESX)を新しいプロジェクトのフォルダにコピーしたのですが、
普通のモジュールは追加>新しい項目の追加でなんとか追加できたのですが、フォームの追加の仕方がわかりません><教えてくださいー

P.S. RESXファイルってフォームのデータが入ってるのでしょうか?そんな気がしてコピーしたのですが。

※VB6.0からVB.NETに以降した際にアップデート情報みたいなのがプログラム上にくっついてしまって.vbファイルも参照項目も増えまくってしまった

Aベストアンサー

ドラッグ&ドロップが使いやすい。
Windowsのエクスプローラでvbファイルをドラッグして、VS.NETのソリューションエクスプローラへドロップする。

QConsole.WriteLine で表示されない

VB2008でプログラムミングしておりますが、プログラミング試験の為によく使われる、「Console.WriteLine」ですが、表示されないのです。
何処に表示されるのでしょうか。
デバックを行っても何処にも表示されません。

Console.WriteLine("Hello World")
でも表示が何処にも有りません。

初歩的な質問ですが、私には大事な一歩なので宜しく御願い致します。

Aベストアンサー

質問者さんはもう見ていないかもしれませんが、一つ。
質問者さんはプロジェクトのタイプをFormにしているので、コンソールに表示されないのです。
プロジェクトのタイプをコンソールアプリケーションにすれば良く見られるDOS窓に表示されます。
Formアプリケーションタイプでも、確かプロジェクトのプロパティをいじればできたはずです。

QVBでグローバル変数を宣言するには

VB初心者ですが。クイズゲームのようなものを作成したいと考えてます。
Private Sub ~ End Sub の中で宣言した変数って他のところに呼び出したり(戻り値として渡す)出来るのでしょうか?
どこでも、いつでも呼び足せるグローバル変数の宣言とはどのようにやるのか、具体的に教えていただけないでしょうか?

Aベストアンサー

>Public a as Integerのように宣言して、初期化するにはどのように記述を行えばよいですか?

>Public a As Boolean = 0
のように記したら”コンパイルエラー”と出ました。

Booleanって整数値取れたかなと思いつつ。
Sub~End Sub内でa = 0を代入したりしてください

扱おうと言うことがあるかどうか疑問だけど

Public Const a As Integer = 10 'グローバルな定数の宣言

QVB.NETでのnothing の意義について

 VB.NET(.NET環境)ではガーベジコレクションがあるので、オブジェクトの解放はそれほど気を使わなくても良いようですが、やはり明示的に解放したいときがあります。

 例えば下記のようにオブジェクトを解放してから確保したいときなどです。

objMyFile As clsMyFileClass = New clsMyFileClass("SAMPLE1.TXT")
objMyFile.Write("TEST")
objMyFile = Nothing ←ここで解放したい
objMyFile = New clsMyFileClass("SAMPLE2.TXT")
objMyFile.Write("TEST")

 このクラスの Finalize でファイルクローズするようにした場合、Nothing を代入しても Finalize が実行されないようです。

 また、GC.Collect()を使用すると他のオブジェクトのコレクションも実行されるので、ちょっと大げさな感じがします。

 Open と Close メソッドを追加すれば解決しますが、せっかくなので New と Finalize で処理するようにしたいです。なお、VB.NET 2003なのでUsing も使えません。

 VB.NET(.NET環境)ではガーベジコレクションがあるので、オブジェクトの解放はそれほど気を使わなくても良いようですが、やはり明示的に解放したいときがあります。

 例えば下記のようにオブジェクトを解放してから確保したいときなどです。

objMyFile As clsMyFileClass = New clsMyFileClass("SAMPLE1.TXT")
objMyFile.Write("TEST")
objMyFile = Nothing ←ここで解放したい
objMyFile = New clsMyFileClass("SAMPLE2.TXT")
objMyFile.Write("TEST")

 このクラスの Finalize でファイルクローズ...続きを読む

Aベストアンサー

どんなにがんばっても、明示的に開放することはできません。
nothingすることは、オブジェクトをその変数が参照していない事を示す以外の目的では使えません。
GC.Collect() しても、開放されるかどうか確定しているわけではありません。
open/closeメソッドを追加しても、finalizeしても、解決しません。
表向き使えなくなっているだけで、実際に開放されるかどうかは、.NET Frameworkまかせです。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング