- PR -

くだらない質問なんですが・・

投稿者投稿内容
eno
常連さん
会議室デビュー日: 2008/08/22
投稿数: 28
お住まい・勤務地: 代々木上原
投稿日時: 2008-08-22 16:27
くだらない質問なんですが・・
Dispose()されたあとでもインスタンスの再利用(!?)ができているので、
自分の認識と違うなと。。。。

http://www.google.co.jp/search?hl=ja&q=close%E3%81%A8dispose&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=

状況は
OpenFileDialogのクラスメンバ利用のところだけ部品化して、同じクラスだったら呼び出せるレベルにしてあります。問題コードは長コメントのところです。
正しい理解されてる方宜しくお願いします。

private System.Windows.Forms.OpenFileDialog openFileDialog1;
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();

call_OpenFileDialog{
 this.openFileDialog1.FileName = "Player Arguments";
this.openFileDialog1.InitialDirectory = @"C:\openvideo\waves";
this.openFileDialog1.DefaultExt="wav";
this.openFileDialog1.RestoreDirectory = true;
this.openFileDialog1.CheckFileExists = true;
this.openFileDialog1.CheckPathExists = true;
this.openFileDialog1.Filter = "WMPファイル(*.wav;*.wav)|*.wav;*.wav|nicoファイル(*.flv;*.flv)|*.flv;*.flv|すべてのファイル(*.*)|*.*";
this.openFileDialog1.FilterIndex = 2;
this.openFileDialog1.Title = "開くファイルを選択してください。";

//
// nothing doing , then return
//
if (this.openFileDialog1.ShowDialog() != DialogResult.OK)
{
Form2_public_cnt = 0;
this.openFileDialog1.Dispose();
return;
}

this.openFileDialog1.Dispose();/*このステップでインスタンスは破棄されているのでは?
this.FileName = this.openFileDialog1.FileName;//コンパイル・実行と正常終了できました。シーケンスをひっくり返したときに期待される結果と同じで、これはインスタンスは死んでないなという感じです。CLIのgc機能は明示的には呼び出し・実行できない仕様と理解していて、DisposeはCLIのマネージメントに依存するということでしょうか?*/

this.button4.Enabled = true;
this.axWindowsMediaPlayer1.Dock = DockStyle.Fill;
this.axWindowsMediaPlayer1.URL = this.FileName;
this.axWindowsMediaPlayer1.settings.setMode("loop", true);
}


eno
常連さん
会議室デビュー日: 2008/08/22
投稿数: 28
お住まい・勤務地: 代々木上原
投稿日時: 2008-08-22 16:31
すみません、修正・補正しました。
こちらのコードを正でお願いします。

private System.Windows.Forms.OpenFileDialog openFileDialog1;
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();

call_OpenFileDialog{

this.openFileDialog1.FileName = "Player Arguments";
this.openFileDialog1.InitialDirectory = @"C:\openvideo\waves";
this.openFileDialog1.DefaultExt="wav";
this.openFileDialog1.RestoreDirectory = true;
this.openFileDialog1.CheckFileExists = true;
this.openFileDialog1.CheckPathExists = true;
this.openFileDialog1.Filter = "WMPファイル(*.wav;*.wav)|*.wav;*.wav|nicoファイル(*.flv;*.flv)|*.flv;*.flv|すべてのファイル(*.*)|*.*";
this.openFileDialog1.FilterIndex = 2;
this.openFileDialog1.Title = "開くファイルを選択してください。";

//
// nothing doing , then return
//
if (this.openFileDialog1.ShowDialog() != DialogResult.OK)
{
Form2_public_cnt = 0;
this.openFileDialog1.Dispose();
return;
}

this.openFileDialog1.Dispose();//このステップでインスタンスは破棄されているのでは?
this.FileName = this.openFileDialog1.FileName;

/*コンパイル・実行と正常終了できました。シーケンスをひっくり返したときに期待される結果と同じで、これはインスタンスは死んでないなという感じです。CLIのgc機能は明示的には呼び出し・実行できない仕様と理解していて、 DisposeはCLIのマネージメントに依存するということでしょうか?*/

this.button4.Enabled = true;
this.axWindowsMediaPlayer1.Dock = DockStyle.Fill;
this.axWindowsMediaPlayer1.URL = this.FileName;
this.axWindowsMediaPlayer1.settings.setMode("loop", true);
}
どっとねっとふぁん
ぬし
会議室デビュー日: 2005/02/23
投稿数: 935
投稿日時: 2008-08-22 16:35
ガベージコレクタが実際にメモリを回収するまでの間の状態なんじゃないでしょうか。
ドキュメントだとこのあたり。
http://msdn.microsoft.com/ja-jp/library/ms404247(VS.95).aspx
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2008-08-22 16:51
引用:
ドキュメントだとこのあたり。
http://msdn.microsoft.com/ja-jp/library/ms404247(VS.95).aspx
SIZE="1" WIDTH="100%">

この問題に弱参照(WeakReference)は無関係です。


Dispose はインスタンスを破棄する特殊なメソッドではありません。ただの一般的なそこらに定義されてるメソッドと変わりありません。
Dispose が呼ばれようと呼ばれまいと、インスタンスが解放されるのは GC されたときであり、それにはどこからも参照されていない(相互参照とか弱参照とか特殊な場合もありますが)状態になっていることが必要です。
じゃあ Dispose は何するのかというと、一般的には、「すぐ解放すべきものの解放処理」を実装させます。ファイルのロック解除とか。
その結果、一部のプロパティやメソッドは参照不可になって ObjectDisposedException などが投げられる可能性はありますが、それに関わらないものなら普通に呼び出せます。まあ普通は Dispose 後は触りませんけどね。

[ メッセージ編集済み 編集者: Hongliang 編集日時 2008-08-22 16:52 ]
eno
常連さん
会議室デビュー日: 2008/08/22
投稿数: 28
お住まい・勤務地: 代々木上原
投稿日時: 2008-08-22 17:08
レスありがとうざいます。

>>その結果、一部のプロパティやメソッドは参照不可になって ObjectDisposedException などが投げられる可能性はありますが、それに関わらないものなら普通に呼び出せます。まあ普通は Dispose 後は触りませんけどね。

一部には、Disposedが適用されることもあるということでしょうか。。
フォームアプリが使用中のオブジェクトはgcの対象にはならないというのは理解できますが、
ユーザ側でインスタンスの破棄ができないのでは、フォームを破棄していく
しか代替はないということでしょうか?フォームベースの設計が大事になりますね。


Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2008-08-22 17:31
引用:

一部には、Disposedが適用されることもあるということでしょうか。



多分お考えになっているのとは違います。
そのクラスが、「Dispose されてたら取得(とか実行とか)できねーや」と判断して自前で投げるだけです。フレームワークは面倒見ません。
こんなのは別に Dispose に限ったことではなく、例えば Process インスタンスを Start 呼び出す前に Kill したときに InvalidOperationException が投げられるのと全く変わりません。

引用:

フォームアプリが使用中のオブジェクトはgcの対象にはならないというのは理解できますが、
ユーザ側でインスタンスの破棄ができないのでは、フォームを破棄していく
しか代替はないということでしょうか?フォームベースの設計が大事になりますね。



フォームの破棄って意味が良くわかりません。
インスタンスの破棄ってのも、.NET が想定するものとは違いがありそうです。
eno
常連さん
会議室デビュー日: 2008/08/22
投稿数: 28
お住まい・勤務地: 代々木上原
投稿日時: 2008-08-22 17:51
自前で投げるだけです。フレームワークは面倒見ません。 >>

はい、例外クラスを生成するのは呼び出したほうなのは理解しています。
フレームワーク(gc)は関与していないのも了解です。ご指摘助かります。

>>フォームの破棄って意味が良くわかりません。

これは言葉のあやの問題だと思います。
メモリを解放するとか、disposeするとかcloseするとかfreeとかreleaseだとか言い方・表現の違いにすぎないです。.NETが想定するものとは具体的にどういったものかお考えきかせてください。今回はメモリ解放のタイミングが主題で、どの言語でもそれ以外は変わらないはずです。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2008-08-22 22:33
引用:
>>フォームの破棄って意味が良くわかりません。

これは言葉のあやの問題だと思います。
メモリを解放するとか、disposeするとかcloseするとかfreeとかreleaseだとか言い方・表現の違いにすぎないです。.NETが想定するものとは具体的にどういったものかお考えきかせてください。今回はメモリ解放のタイミングが主題で、どの言語でもそれ以外は変わらないはずです。


.NET ではメモリの解放と Dispose や Close の呼び出しはまったく関係ありません(アンマネージドなメモリは除きますけど)。ですので言葉の綾などではなく明確に区別しなければならない問題です。
そして、GC はメモリ管理の機構であり、それ以外のリソース、ファイルハンドルであるとか GDI ハンドルであるとかは GC 自体は関知しません。
また、GC の基本的前提は「メモリは貴重ではないリソースである」です。貴重ではないのである程度溜まってから整理すれば十分なのです。それで十分なら、メモリ解放のタイミングなど問題になりません。

「Form の破棄」が「Form のインスタンスが GC によって回収された」と同義であるとして、「ユーザ側でインスタンスの破棄ができない」から「フォームを破棄」で「代替」するというのは意味が分かりません。
インスタンスの破棄は参照が無くなったら GC がそのうち行います。あるクラス Hoge のフィールドとして宣言されているインスタンスなら、そのフィールドに null やほかのインスタンスが代入されたとき、そのフィールドがもともと参照していたインスタンスは GC の対象になります(それ以外から参照されていなかった場合)。もちろん、Hoge クラスのインスタンス自体が参照されなくなった場合も GC の対象になりますし、大抵のフィールドはその宣言するクラスのインスタンスと必要な寿命が一致するでしょうけど。
また Dispose は通常インスタンスが不要になったらさっさと呼び出すメソッドです。GC が回収する際に呼び出すファイナライザで不都合が起きないような実装になってはいるでしょうが、そのいつになるか分からない回収までの間ファイルがロックされてたりメモリよりずっと貴重なハンドル類が占有されたりということを避けるためです。

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