user829174
user829174

Reputation: 6362

FileSystemWatcher getting too many event

I'm trying to implement a file watcher that will raise an event if the file content was changed. The problem that once the file I am watching was modified, I am getting 2 events. (I want to get it only once)

_automationStatusWatcher = new FileSystemWatcher(fileInfo.Directory.FullName,
                                                 fileInfo.Name);
_automationStatusWatcher.NotifyFilter = NotifyFilters.LastWrite;
_automationStatusWatcher.Changed += OnAutomationStatusChanged;
_automationStatusWatcher.EnableRaisingEvents = true;

The file that i'm watching is not intended to be recreated/moved/deleted/whatever. its purpose is to be an xml database file that i need to monitor it once it changes. i want to get only 1 event when the file is modified and to ignore the other events.

How can I do that?

Upvotes: 1

Views: 8852

Answers (6)

dsingleton
dsingleton

Reputation: 1006

If you look at the documentation for FileSystemWatcher it says that it will fire multiple times.

Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Likewise, some applications (for example, antivirus software) might cause additional file system events that are detected by FileSystemWatcher.

I would recommend doing some kind of queuing mechanism so that you don't have multiple actions on the same file.

Upvotes: 0

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112712

I had to cope with this problem some time ago. I wanted to be notified when a file was created. The problem was that the event is triggered when the file is still empty or still being written to, not when the new file is closed.

The solution was to create the file using a temporary name and when finished renaming the file to its final name. I then watched for the rename-event.

You could name the file to myfile.tmp while writing to it and when finished rename it to myfile.xml and watch the rename-event.

Upvotes: 2

Inshua
Inshua

Reputation: 1505

i meet this problem too, now i found out this way :

new Thread(() => {
            while (true) {
                var r = watch.WaitForChanged(WatcherChangeTypes.All);
                this.Invoke(new ThreadStart(() => {
                    listBox1.Items.Add(string.Format("{0} {1} {2}", DateTime.Now, r.Name, r.ChangeType));
                }));
            }
        }) { IsBackground = true }.Start();

its very similar to nio in java

Upvotes: 1

brgerner
brgerner

Reputation: 4371

I had a similar problem for checking updates in logging configurations.
I read about the multiple events problem of FileSystemWatcher. So I decided to implement another solution.

I check for every access to my configuration file if it has changed by comparing modified date. Later I added a latence (2 seconds) to avoid too many accesses to filesystem. Maybe you can also use that way.

Upvotes: 0

JamieB
JamieB

Reputation: 348

You could attempt to unhook your event handler once you catch a change until you are ready to accept more changes:

_automationStatusWatcher.Changed -= OnAutomationStatusChanged;

But that is not necessarily thread safe and you could get multiple firings anyway. Another option is to use a semaphore variable to see if you are handling the change:

private bool _inStatusChange = false;
private void OnAutomationStatusChanged(object sender, args...)
{
    if (_inStatusChange)
    {
        return;
    }
    else
    {
         _inStatusChange = true;
        //do work
        _inStatusChange = false;

    }
}

You should use appropriate locking to keep access to the semaphore variable thread safe.

Upvotes: 1

CodeCaster
CodeCaster

Reputation: 151720

Manual:

Note

Common file system operations might raise more than one event. For example, when a file is moved from one directory to another, several OnChanged and some OnCreated and OnDeleted events might be raised. Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Likewise, some applications (for example, antivirus software) might cause additional file system events that are detected by FileSystemWatcher.

Upvotes: 2

Related Questions