views:

220

answers:

3

Hello,

I'm doing a join of multiple multi-image tiff files to a single multi-image tiff file and have a problem with deleting the source tiff files, because the Image class continues to hold the handle on them.

I'm reading a tiff image through Image.FromFile:

Bitmap resultTiff = (Bitmap) Image.FromFile(strImageFile);

After which I read all other tiff images the same way and append them to the resulting tiff image.

When I finish I use this code to release references and to save resulting file:

ep.Param[0] = new EncoderParameter(enc, (long) EncoderValue.Flush);
resultTiff.SaveAdd(ep);
resultTiff.Dispose();

Now the problem is that the handle on the files still exists (and therefore files can't be deleted) unless I call the GC.Collect() after the resultTiff.Dispose() call.

You can imagine that I don't feel very comfortable by calling GC, so is there any other way of achieving this?

+1  A: 

You can try:

resultTiff = null;
fARcRY
ass much as you shouldnt need to do this - it works. I had an image app that loaded 1000's of images in a loop and processed them. if i didn't have `img = null` in the loop i would get OOM errors very quickly.
Pondidum
@Pondium: I've had that problem, too. As a sidenote, I suspect that it might not solely be caused caused by insufficient memory, but by a lack of GDI handles, as well.
stakx
+5  A: 

Or try:

Using(Bitmap resultTiff = (Bitmap) Image.FromFile(strImageFile))
{
   ep.Param[0] = new EncoderParameter(enc, (long) EncoderValue.Flush);
   resultTiff.SaveAdd(ep);
}
rdkleine
While using `using` is definitely a good recommendation, it probably won't solve Goran's particular problem. The example code given in the question already calls `Dispose` (in non-exceptional circumstances).
LukeH
Thank you guys for your response. It just happened that I had a glitch somewhere else in the code, and when I fixed that using of just Dispose solved my problems.I wasn't disposing references to the files I was _appending_ to the first file. When I corrected this, everything started working great.
Goran
+3  A: 

The best way to solve the issue with Image.FromFile wherein it leaves file handles open is to use Image.FromStream instead.

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
   using (Image original = Image.FromStream(fs))
   {
      ...

Using an explicit Dispose(), a using() statement or setting the value to null doesn't solve the issue until a garbage collection happens. Forcing a garbage collection to happen is generally a bad idea.

Hightechrider
+1 for this answer. `Image.FromFile` does not always do exactly the right thing. Replacing it by manually opening a file stream and then loading the bitmap from there gives you some more flexibility.
stakx