I am writing a piece of .NET code which needs to overwrite image files in a website hosted on IIS 6 or 7. The only processes that should be touching the images are IIS and m
By serving means, I assume its reading the files and delivering to clients(browser). For this opration it is not at all needed to lock the file. So We can assume that it is opening the file in Read mode. IIS uses TransmitFile() API to send files over sockets. It is using OS internal cache for performance and should not lock the file.
we can view which file is opened by what process using processexplorer from sysinternals. This would help you to find if its actually opened by any other process.
IIS will lock the files.
How about writing an HttpHandler for images, so that you have direct control over how the images are served and where from.
Since you then control how the images are served and how the images are replaced, all you need to design is a common locking mechanism to maintain order.
Even though IIS may lock the file when it's read, you might be able to rename the file out of the way and replace it with your new version. This strategy can also be used to defeat the 'half-written-file' problem, where a file starts to be read before it's completely written.
This is possible, given that while any file is being read, it is locked during the read, so you could run into a situation where IIS is reading and serving the file, and you're trying to write to the file at the same time.
This and this may provide some help with waiting for the file, then locking it. Bear in mind that you could cause IIS to respond slower as it waits for the file as well.
The short answer will be to try open the file, if failed, wait for a few seconds and try again, loop until success or timeout.
However, if you are updating these images a lot, you're really defeating IIS's caching mechanisms here. And it is not healthy for the web server to be serving files that are constantly changing. Web servers are great at serving static files.
Now if your images are so dynamic, perhaps you'll need to serve it through a server-side program instead. Generate your images (or read it from another program via remoting or WCF) and serve it. Your server-side program may also do some form of caching. No need even to keep an image file if it only lasts a very short time.
If you only need to replace those images occasionally, then it is ok to keep retrying.
Now if those images are really important, and you really would like IIS to stop serving the old version as soon as you have a new version (are you serving a CAPTCHA?), and IIS is serving this same file many many times per second, then your process may not be able to find a slot in. Then you'll either need to find a way to tell IIS to stop and wait for the new version -- restarting it should work, since you are not changing images often (otherwise, you'd have gone with the dynamic route).