This article discusses an enhanced
FileSystemWatcher class which can be used to suppress duplicate events that fire on a single change to the file.
System.IO.FileSystemWatcher class helps the user to monitor a directory and multiple or single file within a directory. Whenever a change (Creation, Modification, Deletion or Renaming) is detected, an appropriate event is raised. However, duplicate events fire depending on the software that is being used to modify the file.
Using Notepad, modifying the contents of a file results in 2 Changed events being fired. Doing the same using Textpad results in 4 Changed events being fired.
Using Textpad, creating a file in a directory that was being watched resulted in 1 Created and 3 Changed events being fired. In case of Notepad, Created followed by Deleted!!, followed by Created and 3 Changed Events were observed.
My guess is that multiple events are fired depending on number of times the file system is accessed by particular software while performing any given operation (Save, Delete, Save As, etc.).
We need to keep track of the event as they get fired and suppress subsequent events that occur within pre-determined interval.
We create a class "
MyFileSystemWatcher" that inherits from
System.IO.FileSystemWatcher. We also create a dictionary to keep track of when the last event occurred for a file, along with some other
public class MyFileSystemWatcher : FileSystemWatcher, IDisposable
#region Private Members
private Dictionary<string,> _lastFileEvent;
private int _interval;
private TimeSpan _recentTimeSpan;
We delegate the construction of the object to
FileSystemWatcher Base class and initialize the
private members in the
InitializeMembers private method.
public MyFileSystemWatcher() : base()
public MyFileSystemWatcher(string Path) : base(Path)
public MyFileSystemWatcher(string Path, string Filter) : base(Path, Filter)
private void InitializeMembers()
Interval = 100;
FilterRecentEvents = true;
_lastFileEvent = new Dictionary<string,>();
base.Created += new FileSystemEventHandler(OnCreated);
base.Changed += new FileSystemEventHandler(OnChanged);
base.Deleted += new FileSystemEventHandler(OnDeleted);
base.Renamed += new RenamedEventHandler(OnRenamed);
We create a method to determine if a recent event has occurred for a particular file.
private bool HasAnotherFileEventOccuredRecently(string FileName)
bool retVal = false;
DateTime lastEventTime = _lastFileEvent[FileName];
DateTime currentTime = DateTime.Now;
TimeSpan timeSinceLastEvent = currentTime - lastEventTime;
retVal = timeSinceLastEvent < _recentTimeSpan;
_lastFileEvent[FileName] = currentTime;
retVal = false;
We create Event Handler for base class event; check if a recent event has occurred and if not we raise the event. The code snippet shows this approach for "
Changed" event only, see attached code for other events like "
Renamed" and "
public new event FileSystemEventHandler Changed;
private void OnChanged(object sender, FileSystemEventArgs e)
protected new virtual void OnChanged(FileSystemEventArgs e)
if (Changed != null) Changed(this, e);
Figure 1 - Observing a file Test.txt using System.IO.FileSystemWatcher when editing file using Textpad.
Figure 2 - Observing a file Test.txt using Temp.IO.MyFileSystemWatcher when editing file using Textpad.
public interface of this class matches that of a file system watcher class so it can be replaced easily across code, especially if you are using a
Factory to create a
Other situations might arise that this code does not handle (based on what software is being used to edit the file). Constructive criticism is welcome. Hope this is useful for some readers.
- 16th August, 2010: Initial post