Where is the proper place to dispose an image

2019-09-14 22:03发布

问题:

I have a form with OpenFileDialog for selecting image and showing it in pictureBox. Until the form is open the user can open and then save the opened image as many times as he wants. What I want to do is, after each new selection-save, to delete the previously saved image if there is such. The problem is that as I implemented the code now I am able to delete the image the first time, if I keep on saving images with the currently open form I get an error that the resource is being used. What I do is Dispose() the image but I guess I don't do it in the right place.

This is how I open and load the image:

private void btnExplorer_Click(object sender, EventArgs e)
        {

            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Title = "Select file";
            openFileDialog1.InitialDirectory = "c:\\";
            openFileDialog1.Filter = fileNameFilter;
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.FileName = prefixFilter;


            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    pictureBox1.InitialImage = new Bitmap(openFileDialog1.FileName);
                    pictureBox1.ImageLocation = openFileDialog1.FileName;
                    selectedFile = pictureBox1.ImageLocation;
                    selectedFileName = openFileDialog1.SafeFileName;
                    pictureBox1.Load();
                }
                catch (Exception ex)
                {
                    logger.Error(ex.ToString());
                    MessageBox.Show("Error loading image!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

And in the same class I have this method which I call if I need to delete an old image:

public void DeleteImage(AppConfig imagePath, string ImageName)
        {
            pictureBox1.InitialImage.Dispose();//Release the image before trying to delete it
            string imgPath = imagePath.ConfigValue.ToString();
            File.Delete(imgPath + "\\" + ImageName);
        }

As you can see. The Dispose() method is here which I though will ensure that the resource will be disposed before trying to delete it but as I said this only work once and then I get the error as many times as attempts to save image I make.

P.S

The exact error I get is:

The process cannot access the file 'C:\Images\ME_083a210e1a7644198fe1ecaceb80af52.jpg' because it is being used by another process.

回答1:

There is a better way to do it. Load the image using FileStream and than assign it to the pictureBox

FileStream bmp = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
Image img = new Bitmap(bmp);
pictureBox1.Image = img;
bmp.Close();

and if you want to clear the picture box, simply

pictureBox1.Image = null;


回答2:

If I understand this correctly you want to remove the once "used" image from it's picture box: Set

picturebox.InitialImage=null;

(By the way: You better use picturebox.Image ...)

"Dispose" is to force the garbage collector to remove an unused object from memory.

Your error has nothing to do with the disposal of the pictureBox-image but with the lock of the source file.

Maybe it already helps if you use a "using" block for the handling of the openFileDialog.



回答3:

  private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Title = "Select file";
            openFileDialog1.InitialDirectory = "c:\\";
            openFileDialog1.Filter = "Jpeg Files(*.jpg)|*.jpg|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                pictureBox1.InitialImage = new Bitmap(openFileDialog1.FileName);
                pictureBox1.ImageLocation = openFileDialog1.FileName;
                selectedFile = pictureBox1.ImageLocation;
                selectedFileName = openFileDialog1.SafeFileName;
                pictureBox1.Load();

            }


        }

        public string selectedFileName { get; set; }

        public string selectedFile { get; set; }

        private void button2_Click(object sender, EventArgs e)
        {
            pictureBox1.ImageLocation = null;
        }