Search code examples
c#filesystemwatcher

Filesystemwatcher causing "Error too many changes at once in directory C:\"


Like a few others I'm getting the error "Error too many changes at once in directory C:\" from the filesystemwatcher when he does its job. Now if it is c:\ it is clear that there are many changes. BUT in this special case I set the following parameters:

Path = C:\
Filter = "test1.txt"
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName
IncludeSubdirectories = true

I started the watcher and let it run without problems for 4 hours after which Í locked the pc and came back a short while later and suddenly had the error.

Now I'm wondering what could have caused the error in this case. Am I overlooking something important here? OR could it be taht the includesubdirectories parameter lets it check ALL subdirectories of c:\ and ignoring the filter of the single file that exists in C:\ ?


Solution

  • You can increase the Buffer for changes - this helped me once.

    But to look for every change at C:\ with subdirs can maybe cause a lot of workload..

    MSDN FileSystemWatcher.InternalBufferSize Property

    EDIT:

    The Filter gets only checked at the Raising-Method - so internally every change gets recognized by the class.

    I took a look into the framework code as you can see the main raising method .....

        private void NotifyFileSystemEventArgs(int action, string name)
        {
            if (this.MatchPattern(name))
            {
                switch (action)
                {
                    case 1:
                        this.OnCreated(new FileSystemEventArgs(WatcherChangeTypes.Created, this.directory, name));
                        return;
    
                    case 2:
                        this.OnDeleted(new FileSystemEventArgs(WatcherChangeTypes.Deleted, this.directory, name));
                        return;
    
                    case 3:
                        this.OnChanged(new FileSystemEventArgs(WatcherChangeTypes.Changed, this.directory, name));
                        return;
                }
            }
        }
    

    is using this method: "this.MatchPattern(name)" - which look like this:

        private bool MatchPattern(string relativePath)
        {
            string fileName = System.IO.Path.GetFileName(relativePath);
            return ((fileName != null) && PatternMatcher.StrictMatchPattern(this.filter.ToUpper(CultureInfo.InvariantCulture), fileName.ToUpper(CultureInfo.InvariantCulture)));
        }
    

    and as you can see - the filter get checked here - far to late to have suppressed load... ...So the only way is to increase the buffer size!