DisposeしたImage(Bitmap)をPictureBoxに割り当てると「Prameter is valid」

コンピュータ
多数の画像ファイルをキャッシュして、キャッシュからPictureBoxへ画像を割り当てるプログラムを作っていて、「Prameter is valid」と表示され悩んでいました。
再現性もあり、一度表示した画像を再度表示しようとすると発生します。
PictureBoxに画像を割り当てる前に、表示中の画像をDispose()するようにしていたのですが、結果としてキャッシュのImage(Bitmap)をDispose()していることに全く気が付きませんでした。
原因を知れば何のことは無いミスで少し手間をかければ再発防止策もありそうですが、次に同じような状況に遭遇しても同じように悩むことに成りそうな予感がします。

再現プログラム

namespace BitmapDispose;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        string path = @"表示する画像のパス";
        Image? img = null;

        var panel = new FlowLayoutPanel
        {
            Dock = DockStyle.Fill,
        };
        var picbox = new PictureBox
        {
            SizeMode = PictureBoxSizeMode.AutoSize,
        };
        var loadFileBtn = new Button
        {
            Text = "LoadFile",
            AutoSize = true,
        };
        var setImageBtn = new Button
        {
            Text = "SetImage",
            AutoSize = true,
        };
        var disposeBtn = new Button
        {
            Text = "Dispose",
            AutoSize = true,
        };
        panel.Controls.AddRange(new Control[]
        {
            picbox, loadFileBtn, setImageBtn, disposeBtn,
        });
        panel.SetFlowBreak(picbox, true);
        this.Load += (s, e) => this.Controls.Add(panel);
        loadFileBtn.Click += (s, e) =>
        {
            using var fs = new FileStream(path, FileMode.Open);
            img = Bitmap.FromStream(fs);
        };
        setImageBtn.Click += (s, e) =>
        {
            picbox.Image = img;
        };
        disposeBtn.Click += (s, e) =>
        {
            img?.Dispose();
        };
    }
}

実行


次の順番にボタンをおす。「LoadFile」→「SetImage」→「Dispose」→「SetImage」

「Prameter is valid」が表示される。

コメント