0

I'm creating a Windows Forms Application in C#.

I have some buttons on the form and I used the BackgroundImage property to set bitmap images on them.

I wanted to change those images dynamiclly so:

  1. I used using (bitmap = new Bitmap...) and saved a new bitmap picture.

  2. I assign the new bitmap to be on the button.

  3. Then, I tried to delete the old bitmap by calling Dispose() and then System.IO.File.Delete(nameToDelete);

The problem: the File.Delete function throws an exception: "file is being used by another process" and I can't delete it.

I also tried calling GC.Collect() and assigning the bitmap to null but it didn't work.

The only "solution" I find is to call Thread.Sleep(2) before deleting, But it's a patch and doesn't work each time.

Here is the code (layerPics[z] is an array that holds all the bitmaps, one for each button):

string name = "new name";
Bitmap bitmap;
using (bitmap = new Bitmap(x, y))
{
    Form.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
    bitmap.Save(name);
    button.BackgroundImageLayout = ImageLayout.Stretch;
    button.BackgroundImage = Image.FromFile(name);
}
layerPics[z].Dispose();
layerPics[z] = null;
layerPics[z] = bitmap;

What can I do? Thanks!

  • Could you post formatted code, so we can see where you try the `Dispose` and where the scope of your `using` starts/ends, please? – LInsoDeTeh Jul 23 '15 at 11:21
  • Try Thread.Sleep(2000) :) – Disappointed Jul 23 '15 at 11:21
  • 1
    Never use `Application.DoEvents()`. It's evil! – Matthew Watson Jul 23 '15 at 11:28
  • 1
    ...an never rely on `Thread.Sleep`. – Dennis Jul 23 '15 at 11:35
  • I just added the relevant code to the original questions. The layerPics[z] array is of type Image[], but it holds bitmap picture. – user3733449 Jul 23 '15 at 11:36
  • `Image.FromFile(name);` will create an object which keeps `name` open until it's disposed. Try doing `if (Buttons.BackgroundImage != null) Buttons.BackgroundImage.Dispose()` before assigning the new bitmap. – Matthew Watson Jul 23 '15 at 11:38
  • Do you have Explorer open on the directory that contains the image? Or something similar, like Total Commander? Those are usually quite enough to block deleting the file while they generate e.g. thumbnails - instead of just using `Thread.Sleep`, you should simply try deleting the file a few times, with timeouts in between. That said, why are you saving the file in the first place if you want to delete it right after? – Luaan Jul 23 '15 at 11:38
  • For reference, [this](https://stackoverflow.com/a/48170549/395685) is a workaround for the locking problem, which simply copies all byte data from the opened image into a new Bitmap object and then releases the original resource. – Nyerguds Jan 10 '18 at 11:46

1 Answers1

4

It's not the Bitmap that causes the problem, but this line:

Buttons.BackgroundImage = Image.FromFile(name);

Here, you create an instance of an Image class using the factory method FromFile(). The file remains locked until the Image is disposed.

This is the reference.

dymanoid
  • 14,771
  • 4
  • 36
  • 64