views:

436

answers:

3

I have a small C# ASP.NET web application which generates several PNG image files from dynamically created .NET Chart controls. These are then used to:

  • Create a lightbox effect
  • Create a PDF
  • Create a Zip file

The application gets little usage and the data is updated often, so I'm re-creating everything on each load. The problem is, the files are often "in use" and throw an exception when I try to overwrite. I can't have the exception because the correct new versions of the charts need to be displayed, not the old ones. I've thought of deleting first, but still there are problems. Because the page needs to "just work" each time, I've resorted to manually deleting the image files after every data refresh, but this seems ridiculous. I have something like this:

if(!System.IO.File.Exists(Server.MapPath(ImageFilename))) {
    chart.SaveImage(Server.MapPath(imageFilename), ChartImageFormat.Png);
}

And for the PDF, something like this which I know is gross:

try
{
    Document doc = new Document();
    System.IO.File.Delete(Server.MapPath("charts.pdf"));
    PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("charts.pdf"), FileMode.Create));
    doc.Open();
    ///ADD DATA
    doc.Close();
}
catch(Exception exc)
{}

How can I get around the file issues and force an overwrite instead of manual or automatic delete with a swallowed exception? I can always delete just fine in Explorer. Or alternatively, am I thinking about this the wrong way and should try a different tack?

A: 

How about creating the new files with different names, possibly with Date time appended to the file name? Also, create a batch file or windows service to automate the deletion of old files.

jinsungy
+3  A: 

You also need to look at the code that is reading the files and therefore causing the file is not in use error.

Are the files being opened with a lock? Are the files being left open longer than needed? Is the code such that an error will cause the file to be left open?

Your FileMode.Create should delete the file if it already exists.

Shiraz Bhaiji
File access is one of those things where you are dealing with Unmanaged Resources - you need to ensure you're calling Dispose on those objects when you're done with them:
Zhaph - Ben Duguid
@Zhaph - Thanks. Dispose did it for me. I opened up Bitmap objects outside of a 'using' clause
kervin
A: 

Even with advanced windows file caching these days, there's nothing to prevent your code (trying to delete a file) to overlap IIS (trying to cache/serve that same file) so, in case you're not versioning your resources, you could spin and try again several times but that's not that easy to implement and depends also on your resources size. I think the best implementation would be versioning + background cleanup.