1

A file is opened by a thread for writing. The reference to the file is a local variable in a method and therefore unable to be cleaned up by dispose or a finalizer.

The code uses a using statement to make sure that the file is closed and all locks are released during normal operation. However, in the instance of a site be shut down, the using statement might not get a chance to clean up the FileStream. However, the IIS process may stay open, so the lock will not be released unless the server is restarted.

What is the best way to prevent a file lock from hanging if the site is stopped or restarted?

Or does the way IIS shut down a site mitigate this concern?

TheCatWhisperer
  • 901
  • 2
  • 12
  • 28
  • How often does it happen? I mean are you solving a recurring issue or just trying to prevent it hypothetically? – fharreau Sep 12 '17 at 15:42
  • Prevent it hypothetically. Although, I believe this has actually happened to me before. – TheCatWhisperer Sep 12 '17 at 15:43
  • 1
    How did the thread get shut down without the finally blocks on the thread being allowed to run and close the file handle? If the thread is shut down then its local variables are no longer roots; why will the finalizer not run? I don't understand how your scenario is possible. – Eric Lippert Sep 12 '17 at 15:46
  • To the best of my knowledge, you can't avoid it (but I am absolutely not an ASP.Net specialist neither a IIS specialist). How ever, you could probably reduce the lock window by creating a memory copy of the file, modifing it, and "pushing" the modification to the file only at the very end of the process. This way, the file is locked only twice (once during the copy and another during the "push"). If the shutdown occurs during these tiny windows, you are lacking of luck... – fharreau Sep 12 '17 at 15:49
  • @EricLippert If a thread is stopped by the server, it is stopped by the server. It is not within the executing code's control. The finalizers of the `FileStream` will/may eventually be called... but this is non-deterministic and take a long while, especially if there is no memory pressure on the server. – TheCatWhisperer Sep 12 '17 at 15:55
  • @fharreau this particular classes purpose is to deal with datasets that are too large to fit into main memory – TheCatWhisperer Sep 12 '17 at 15:56
  • I never use it myself but that's looks like an application field for the .NET `Memory-Mapped File` API : https://learn.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files – fharreau Sep 12 '17 at 16:04
  • @fharreau: Memory mapped files will not help in this instance. Having a memory mapped file here will just complicate the issue. – Jim Mischel Sep 12 '17 at 21:47
  • @JimMischel As I said, I don't know the constraints of the memory mapped files. But can you explain how it will just complicate the issue? No lock on the actual file, usefull for big files that cannot be loaded in memory, several processes can access concurrently. Looks promising to me. – fharreau Sep 13 '17 at 08:27
  • @fharreau While I am sure memory mapped files are useful, the issue here is not concurrent access, it's just making sure things are cleaned up properly. – TheCatWhisperer Sep 13 '17 at 12:48
  • @fharreau: there's still the problem of the file not being closed properly, meaning that buffers aren't flushed, etc. With potentially many threads writing to the file, you also have problems preventing contention, like when two threads simultaneously try to append. There are other, similar issues. – Jim Mischel Sep 13 '17 at 13:22
  • Do you try something like that: https://stackoverflow.com/questions/4723573/how-to-listen-to-iis-shutdown-event-in-asp-net ? – fharreau Sep 18 '17 at 08:11

1 Answers1

-1

It is a good principle to minimise resource locks as much as possible, and you are seeing one consequence of not doing this. I suggest you only open and lock the file when you actually need to write to it, and release the lock and close the file immediately afterwards. If you are worried about the performance overhead of repeatedly opening the file (and seeking to the end to append), then you should profile the code to see if the performance is acceptable.

Polyfun
  • 9,479
  • 4
  • 31
  • 39
  • 1
    The code in question already minimizes the amount of time File stream is open. But, since the class is a storage utility, it will necessarily have a lot of open `FileStream`s – TheCatWhisperer Sep 12 '17 at 15:52