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

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

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

ImageListのImage.Dispose

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

■94979 / inTopicNo.1)  ImageListのImage.Dispose
  
□投稿者/ OA (5回)-(2020/06/08(Mon) 19:01:10)

分類:[VB.NET/VB2005 以降] 

環境:VB2019、.Net4.7.2、Windowsフォームアプリケーション

ListViewにImageListをセットして、フォルダ内の画像をサムネイルにして表示させています。
対象フォルダを変更した場合、ImageList内のImageを動的に追加、削除しているのですが、
ImageList内のImage.Disposeに関してわからないので、教えてください。

●(質問1)
現在は、破棄用のフィールド変数を用意して、ImageListにAddする時に破棄用のフィールド変数
にも同じImageをAddして以下のようにコーディングしています。
でも★1でFalseと判定され、ResetImageListでDisposeしているImageはImageList内のImageと
別の参照と判定されます。
これだとResetImageList内でImageListのImageをDisposeできていなのか?と思い質問しました。
この認識が正しいなら、ちゃんとDisposeするには、どうすればよいか教えてください。

●(質問2)
https://stackoverflow.com/questions/9515759/disposing-an-imagelist 
の一番最後の所に「ImageListは、イメージを追加すると、元のイメージではなくコピーを追加する」
みたいなことが書いてあるので、★★2の箇所でオリジナル画像をDisposeしているのですが、
この認識は正しいですか?

●(質問3)
どこかのサイトでコントロールを動的に追加削除する場合(今回はコントロールではありませんが)
はClearしてからDisposeとあったので、以来そのようにコーディングしていますが、
どうせ破棄するものを、一旦変数に退避しているので、無駄にメモリを使っているようにも
思うのですがどうなんでしょう?
ローカル変数にせずに、フィールド変数としているのはResetImageList内でローカル変数として
宣言するよりAddの時の方が速度面で有利と思ったからです。


    Private Images As New List(Of Image)

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ResetImageList()
        For Each file In IO.Directory.GetFiles("C:\Test1", "*.jpg")
            Dim img = Image.FromFile(file)
            ImageList1.Images.Add(img)
            Images.Add(ImageList1.Images(ImageList1.Images.Count - 1))
            Debug.WriteLine(ImageList1.Images(ImageList1.Images.Count - 1).Equals(Images(Images.Count - 1))) '★1 
            img.Dispose() '★★2
        Next
    End Sub

    Private Sub ResetImageList()
        ImageList1.Images.Clear()
        For Each img In Images
            img.Dispose()
        Next
        Images.Clear()
    End Sub

引用返信 編集キー/
■94980 / inTopicNo.2)  Re[1]: ImageListのImage.Dispose
□投稿者/ Hongliang (1048回)-(2020/06/08(Mon) 19:26:40)
> ●(質問1)
> 現在は、破棄用のフィールド変数を用意して、ImageListにAddする時に破棄用のフィールド変数
> にも同じImageをAddして以下のようにコーディングしています。
> でも★1でFalseと判定され、ResetImageListでDisposeしているImageはImageList内のImageと
> 別の参照と判定されます。
> これだとResetImageList内でImageListのImageをDisposeできていなのか?と思い質問しました。
> この認識が正しいなら、ちゃんとDisposeするには、どうすればよいか教えてください。
ImageList::Clearを呼び出せば、内部でよろしくやってくれます。
ちなみにそもそもImageListはImageオブジェクトとして保持してるわけではありません。
もちろんImageListからImageとして取り出した分については、取り出した人がDisposeする責任を持ちます。

> ●(質問2)
> https://stackoverflow.com/questions/9515759/disposing-an-imagelist
> の一番最後の所に「ImageListは、イメージを追加すると、元のイメージではなくコピーを追加する」
> みたいなことが書いてあるので、★★2の箇所でオリジナル画像をDisposeしているのですが、
> この認識は正しいですか?
そうですね。
ImageListにAddするためだけにNew Bitmapしてるなら、Usingしてしまった方が楽でしょう。

> ●(質問3)
> どこかのサイトでコントロールを動的に追加削除する場合(今回はコントロールではありませんが)
> はClearしてからDisposeとあったので、以来そのようにコーディングしていますが、
Controlの場合、親のDisposeを呼べばControlsに含まれるDisposeも再帰的に呼び出されますが、親から外した場合Disposeは外した側の責任になります。

> どうせ破棄するものを、一旦変数に退避しているので、無駄にメモリを使っているようにも
> 思うのですがどうなんでしょう?

ちょっと主張がよく分かりませんでした。

> ローカル変数にせずに、フィールド変数としているのはResetImageList内でローカル変数として
> 宣言するよりAddの時の方が速度面で有利と思ったからです。
なぜそう思ったのかよく分かりませんが、意味のある差はないです。
引用返信 編集キー/
■94985 / inTopicNo.3)  Re[2]: ImageListのImage.Dispose
□投稿者/ OA (6回)-(2020/06/09(Tue) 08:04:02)
No94980 (Hongliang さん) に返信

Hongliang様、前回に引き続き、ご指導、ありがとうございます。

> ImageList::Clearを呼び出せば、内部でよろしくやってくれます。
そうだったんですね。
一応、質問する前にソースも調べて、内部のImageをDisposeしてるような箇所がなかったので、判りませんでした。
https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ImageList.cs,9681470aadc12afa,references

最初のURLでも「However you should call imageList.Images.Clear(); in your Dispose().」とあったのですが、
「各々のImageをDispose、かつClearもしなさいよ」という意味だと思ってました。

どうも、ありがとうございました。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


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

このトピックに書きこむ