Coder Perfect

FileSystemWatcher The event that has been changed is raised twice.

Problem

I have an application that searches for a text file and uses the OnChanged eventhandler to handle any changes to the file. NotifyFilters is what I’m utilizing. LastWriteTime but still the event is getting fired twice. Here is the code.

public void Initialize()
{
   FileSystemWatcher _fileWatcher = new FileSystemWatcher();
  _fileWatcher.Path = "C:\\Folder";
  _fileWatcher.NotifyFilter = NotifyFilters.LastWrite;
  _fileWatcher.Filter = "Version.txt";
  _fileWatcher.Changed += new FileSystemEventHandler(OnChanged);
  _fileWatcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
   .......
}

When I modify the text file version.txt and save it, the OnChanged method is called twice.

Asked by user214707

Solution #1

Unfortunately, the FileSystemWatcher class has a well-known bug/feature. This is taken from the class’s documentation:

This section focuses on the Created event, but the same principles apply to other file events. You may be able to get around this in some apps by utilizing the NotifyFilter property, but my experience suggests that you may need to do some manual duplicate filtering (hacks) as well.

I bookmarked a link with a few FileSystemWatcher suggestions a while back. You might want to have a look at it.

Answered by Jørn Schou-Rode

Solution #2

In my delegate, I “solved” that problem by implementing the following strategy:

// fsw_ is the FileSystemWatcher instance used by my application.

private void OnDirectoryChanged(...)
{
   try
   {
      fsw_.EnableRaisingEvents = false;

      /* do my stuff once asynchronously */
   }

   finally
   {
      fsw_.EnableRaisingEvents = true;
   }
}

Answered by David Brabant

Solution #3

By examining the File, any repeated OnChanged events from the FileSystemWatcher can be discovered and eliminated. Get the file’s last write time with GetLastWriteTime. As follows:

DateTime lastRead = DateTime.MinValue;

void OnChanged(object source, FileSystemEventArgs a)
{
    DateTime lastWriteTime = File.GetLastWriteTime(uri);
    if (lastWriteTime != lastRead)
    {
        doStuff();
        lastRead = lastWriteTime;
    }
    // else discard the (duplicated) OnChanged event
}

Answered by BaBu

Solution #4

Here is my method for preventing the event from being raised twice:

watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;

I’ve only set the Filename and size properties in the NotifyFilter property. My FileSystemWatcher object is named watcher. Hope this will help.

Answered by Deepashri

Solution #5

In my circumstance, I have a virtual computer running a Linux server. On the Windows host, I’m working on files. When I make a modification to a folder on the host, I want all of the changes to be synced and uploaded through Ftp to the virtual server. When I write to a file, I use the following method to avoid the duplicate change event (which also marks the folder containing the file as modified):

private Hashtable fileWriteTime = new Hashtable();

private void fsw_sync_Changed(object source, FileSystemEventArgs e)
{
    string path = e.FullPath.ToString();
    string currentLastWriteTime = File.GetLastWriteTime( e.FullPath ).ToString();

    // if there is no path info stored yet
    // or stored path has different time of write then the one now is inspected
    if ( !fileWriteTime.ContainsKey(path) ||
         fileWriteTime[path].ToString() != currentLastWriteTime
    )
    {
        //then we do the main thing
        log( "A CHANGE has occured with " + path );

        //lastly we update the last write time in the hashtable
        fileWriteTime[path] = currentLastWriteTime;
    }
}

I primarily use a hashtable to keep track of file write times. Then, if the hashtable contains the modified filepath and its time value is the same as the currently alerted file’s change, I know it’s a duplicate event and disregard it.

Answered by Ikon

Post is based on https://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice