Filesystemwatcher VS Polling to Watch For File Changes

FileSystemWatcher vs polling to watch for file changes

I have seen the file system watcher fail in production and test environments. I now consider it a convenience, but I do not consider it reliable. My pattern has been to watch for changes with the files system watcher, but poll occasionally to catch missing file changes.

Edit: If you have a UI, you can also give your user the ability to "refresh" for changes instead of polling. I would combine this with a file system watcher.

What does polling mean in the context of watching for file changes?

Polling means here that you regularly read for instance the last write-time of the files you want to watch and test if there is a difference. you could even read the file contents and compare it with a previous verison. Polling just means that you actively do the comparison instead of being notified.

Polling is best avoided for its cost. But if needed then it is needed.

https://en.wikipedia.org/wiki/Polling_(computer_science)

Regarding FileSystemwatcher. It is not perfect but in my experience correct enough in the majority of the cases . I assume that all watchers in developer tools use that mechanism and it is for instance good enough there. I suggest to try it first for your purpose before polling.

Would watching a file for changes or redundantly querying that file be more efficient?

Event-based are always more efficient than polling using the same or spawning a new thread, so it's the right idea to use FileSystemWatcher. The programming model, which uses delegates is also more elegant in my opinion.

C# FileSystemWatcher not firing on Nas file system when making change from different computer

There is plenty of questions on this site that discuss FileSystemWatcher reliability and the conclusion is always the same: it is not reliable.

  • How reliable is the FileSystemWatcher in .netFramwork 4?
  • FileSystemWatcher vs polling to watch for file changes
  • C# FileSystemWatcher watch changes on network drive which is only done by current system
  • FileSystemWatcher events raising twice despite taking measures against it
  • Why are FileSystemWatcher Attribute changes detected on Windows 7 but not Windows 8?
  • and the list goes on and on...

The article from Peter Meinl Tamed FileSystemWatcher describes the limitations in great detail and also provides a more reliable solution.

How can i use FileSystemWatcher to watch for file size changes?

This is quite a common problem when using the file system to communicate between two applications. In my experience it works best if you also have a marker file indicating that the "real" file was written completely:

SystemA: Writes file theRealFile.txt
SystemA: Writes file theRealFile.rdy (0byte)
SystemB: Watches for .rdy files and then reads theRealFile.txt

FileSystemWatcher pitfalls

FileSystemWatcher will not usually miss files. However:

  • since it's based on ReadDirectoryChangesW, it only detects changes to the file's directory entry, not changes to the file itself. Most changes to the file will update the directory entry, but there are a few exceptions (see this article).
  • the buffer for file change notifications has a limited size; if you don't process the events fast enough, the buffer will overflow, causing you to miss events. That's why you should not do any heavy processing in the event handler; if you can't handle the events fast enough, just add them to a queue that you process on another thread.

Other pitfalls:

  • The notifications don't arrive instantly; the delay between the actual change and the notification is usually very short, but I've seen it grow to as long as several seconds. This is not a major issue for most use cases, but depending on what you're trying to do, it could be a problem.
  • There is no event for Moved. If you move a file from a directory to another, you will receive two notifications : Deleted and Created
  • Sometimes, depending on the volume configuration, the paths in the notifications can be in the old 8.3 format (e.g. you can get SOMETH~1.TXT instead of Something.txt)
  • If you move an existing, non-empty directory into the watched directory, you will only get a notification for the directory itself, not its content. You will need to examine the content manually.
  • Changed events can occur several times for the same file; you need to handle the duplicates yourself

C#: Using FileSystemWatcher to watch for changes to files

It's enough if you create a watcher for each directory (and optionally, you can have the watcher to monitor a whole directory tree.) You can then use the events to compare the changed files with the list of files you are interested in.

I would suggest you make some kind of "nanny" class for the watchers to ensure you doesn't dispose active watchers, or create duplicate. Just a tip :)

Btw, yes, there's a limit, you can't create infinite watchers. In specific scenarios that can be a problem, but most likely, that's not the case for you

C# FileSystemWatcher watch changes on network drive which is only done by current system

FileSystemWatcher may notify you that something happened, and you might also be able to deduce what happened, but don't count on it. It's a quite limited and unreliable component in my (and others') experience. So if there is any chance of even moderate contention on the target folder I would use some kind of polling solution instead of file watcher.

That said, it won't tell you who did the change. Once you have deduced what has changed, you need to take additional steps for the "who" part. The filesystem stores quite sparse info, you won't find any source machine info. You could try mapping the fileshares that create these changes with different users, as you may deduce the modifying system from that:
Finding the user who modified the shared drive folder files.

If that is not an option, other solutions are much more complicated.

If you have access to the server hosting Z: you could turn on the file audit log for that resource and deduce who the machine was from the event log (event ids 4663 / 5145). The source machine name will be logged in this case. Should be a breeze to enable it if it's a windows server (Directory properties/security/advanced/audit), but reading and synchronizing logs is more complicated.

If none of the solutions above is possible, you may be able to implement a user-space filesystem to proxy your file share, using something like dokan. Source processes would map to your application instead of the fileshare, that way you could raise your own events or just write a detailed audit log to a database or whatever, and then you forward the actual commands to the fileshare. Very expensive and non-trivial solution though. But probably very fun.



Related Topics



Leave a reply



Submit