C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: PictureBoxのImageプロパティの割当について


(過去ログ 63 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■36563 / inTopicNo.1)  PictureBoxのImageプロパティの割当について
  
□投稿者/ たに (13回)-(2009/06/01(Mon) 18:57:40)

分類:[C#] 

お世話になります。他所様のサンプルソースなのですが、
質問させて下さい。

(引用元:http://www.apfield.jp/csgarden/picturebox.html#picturebox7)
-------------------------------
1:FileStream sr = new FileStream("画像の所在を示すフルパス", FileMode.Open,FileAccess.Read);
2:Bitmap bmp = (Bitmap)System.Drawing.Bitmap.FromStream(sr); //Bitmapクラスオブジェクトへ読込み
3:sr.Close(); //ストリームを閉じる
4:pictureBox1.Image=new Bitmap(bmp);  //ピクチャーボックスの画像イメージをBitmapオブジェクトから創成
5:bmp.Dispose();  //Bitmapオブジェクトの廃棄
--------------------------------
(行番号を付加しました。)

質問1.
--------
PictureBoxにイメージを表示させるためのソース部分ですが、
4行目で「pictureBox1.Image=bmp」としないのは何を意図した
ものなのでしょうか?
上記ソースはもちろん動作しますが「pictureBox1.Image=bmp」として
5行目をコメントアウトしても動作しています。

また、仮に「pictureBox1.Image=bmp」とした場合は
必ずどこかで(例えばForm_Closing()とか)でDispose()しなければ
ならないのでしょうか?

内部的な動きとして違いがわかりません。
--------

質問2.
-------
1行目のFileStreamは3行目でClose()を行っていますが、
FileStreamそのものはDispose()していませんが、これは
これで問題ないのでしょうか?

基本的にC#ではどこからも参照されなくなったオブジェクトは
自動的に破棄されると思いますが、それでもnewしたオブジェクトは
使い終わったらDispose()しておけばとりあえず問題ないと言う
認識で間違ってませんか?
(Dispose()に関しては結構色々な場所で議論されてはいますが、
GCとかの話が絡むとお恥ずかしい話、全く理解が出来ていません(--;)

どなたか回答頂けると幸いです。
宜しくお願い致します。

引用返信 編集キー/
■36566 / inTopicNo.2)  Re[1]: PictureBoxのImageプロパティの割当について
□投稿者/ 倉田 有大 (617回)-(2009/06/01(Mon) 19:51:32)
基本的にDisposeは意識しましょう。
どこからも参照されなくなると、そのうちガベージコレクションがファイナライザ経由でDisposeを読んでくれますけど、いつ開放してくれるかわかりません。
イメージオブジェクトなんかは、しっかりと使った後はDisposeしてやらないと、メモリーがどんどんくわれたり、同じ画像が参照できなかったりと、あまりいいことは起こりません。

って?あってる?ガベージコレクトの動作は自身無し!

>1行目のFileStreamは3行目でClose()を行っていますが、
>FileStreamそのものはDispose()していませんが、これは
>これで問題ないのでしょうか?

srがファイルストリームのインスタンスです。他にDisposeしないといけないやつは、とくになさそうですね。
引用返信 編集キー/
■36574 / inTopicNo.3)  Re[1]: PictureBoxのImageプロパティの割当について
□投稿者/ 渋木宏明(ひどり) (1172回)-(2009/06/02(Tue) 09:14:13)
渋木宏明(ひどり) さんの Web サイト
> 4行目で「pictureBox1.Image=bmp」としないのは何を意図した
> ものなのでしょうか?

意味ないと思う。

Image.FromFile() には「Image.FromFile() によって生成されたインスタンスが存命中、元になったファイルを開きっぱなしにする」という既知の問題があるわけですが、その対策なら「画像ファイルを FileStream で開き、Image.FromStream でインスタンスを生成する」だけで十分だったはず。

> また、仮に「pictureBox1.Image=bmp」とした場合は
> 必ずどこかで(例えばForm_Closing()とか)でDispose()しなければ
> ならないのでしょうか?

原則はそうです。

ただし、その Bitmap のインスタンスの寿命を管理するような、何らかのクラスやコンポーネントに引き渡した場合はその限りではありません。

> 1行目のFileStreamは3行目でClose()を行っていますが、
> FileStreamそのものはDispose()していませんが、これは
> これで問題ないのでしょうか?

エラー処理が足りません。

FaileStream でファイル読み込みを行う際などに例外が発生した場合、Close() は実行されません。

なので、using で括るか try ~ finally するかして、きちんと IDisposable.Dispose() が呼び出されることを保証するべきでしょう。

> 基本的にC#ではどこからも参照されなくなったオブジェクトは
> 自動的に破棄されると思いますが、それでもnewしたオブジェクトは
> 使い終わったらDispose()しておけばとりあえず問題ないと言う
> 認識で間違ってませんか?

方向性は間違ってはいませんが、アバウトです。

「なんでもかんでも解放すりゃいい」ってもんではありません。

まず、IDisposable インターフェースを実装しない、純粋にマネージな要素だけで構成されるオブジェクトに関しては、よほど過酷なシナリオでない限り、そのオブジェクトインスタンスが使用していた資源=メモリの管理は GC 任せで問題ありません。

アンマネージリソースをカプセルするかどうかにかかわらず、どこからも参照されなくなったオブジェクトは GC によって「いつか」破棄されます。

IDisposable インターフェースを実装するクラスインスタンスについては、GC によるオブジェクトインスタンスの破棄の際に IDisposable.Dispose() 呼び出しが行われます。

なので、プログラマがうっかりしていても、GC によるオブジェクトインスタンスの破棄の際に IDisposable.Dispose() 呼び出しが行われるのは間違いありません。

ですが、それが「いつ」行わるか、の保証がないのです。

IDisposable インターフェースを実装するオブジェクトについては、「いつ」破棄されるかが重要であることが常です。(たとえば、FileStream をいつまでも Close() しなかったら、そのファイルは別プロセスによって変更・削除できません)

なので、IDisposable インターフェースを実装するクラスのインスタンスに関しては、プログラマ(アプリケーションあるいはフレームワーク、ライブラリなどのプログラマ)が、IDisposable.Dispose() を呼び出すタイミングを積極的に管理するべきなのです。

ただし、例えあなたが書いたコードの中で new されたオブジェクトであっても、「あなたが IDisposable.Dispose() を呼び出すべきかどうか」は、そのオブジェクトの使われ方によって変わります。

引用返信 編集キー/
■36599 / inTopicNo.4)  Re[2]: PictureBoxのImageプロパティの割当について
□投稿者/ たくボン (171回)-(2009/06/02(Tue) 13:36:30)
No36566 (倉田 有大 さん) に返信
> って?あってる?ガベージコレクトの動作は自身無し!

基本的にGCからFinalizeが呼び出されるのは以下の4パターンだったと思う(仕様が変わってなければw)。

1.ジェネレーション0がいっぱいになる。
2.GC.collect()のコール
3.AppDomainのUnload
4.CLRの終了

ここでプログラマが意識しないとダメなのは1番。
ジェネレーション0がいっぱいになるタイミングなんかこっちでは推測できないし、これに頼ってたらリソースの回収がされないまま同じリソースにアクセスしたりしちゃうから、明示的なDisposeが必要なリソースについてはusingとか書く癖をつけるのがいいと思う。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -