Using FileSystemWatcher with multiple files

后端 未结 4 1210
小蘑菇
小蘑菇 2020-12-16 03:27

I want to use FileSystemWatcher to monitor a directory and its subdirectories for files that are moved. And then I want to trigger some code when all the files have been mov

4条回答
  •  失恋的感觉
    2020-12-16 04:25

    Like Jay says: a timer is probably the only way to "group" events. The lock may be overkill but I don't like the idea of mutating a collection in a multithreaded situation (I think the events from the fswatcher are called on threads from a pool).

      public class Monitor : IDisposable
      {
         private List filePaths;
         private ReaderWriterLockSlim rwlock;
         private Timer processTimer;
         private string watchedPath;
         private FileSystemWatcher watcher;
    
         public Monitor(string watchedPath)
         {
            filePaths = new List();
    
            rwlock = new ReaderWriterLockSlim();
    
            this.watchedPath = watchedPath;
            InitFileSystemWatcher();
         }
    
         private void InitFileSystemWatcher()
         {
            watcher = new FileSystemWatcher();
            watcher.Filter = "*.*";
            watcher.Created += Watcher_FileCreated;
            watcher.Error += Watcher_Error;
            watcher.Path = watchedPath;
            watcher.IncludeSubdirectories = true;
            watcher.EnableRaisingEvents = true;
         }
    
         private void Watcher_Error(object sender, ErrorEventArgs e)
         {
            // Watcher crashed. Re-init.
            InitFileSystemWatcher();
         }
    
         private void Watcher_FileCreated(object sender, FileSystemEventArgs e)
         {
            try
            {
               rwlock.EnterWriteLock();
               filePaths.Add(e.FullPath);
    
               if (processTimer == null)
               {
                  // First file, start timer.
                  processTimer = new Timer(2000);
                  processTimer.Elapsed += ProcessQueue;
                  processTimer.Start();
               }
               else
               {
                  // Subsequent file, reset timer.
                  processTimer.Stop();
                  processTimer.Start();
               }
    
            }
            finally
            {
               rwlock.ExitWriteLock();
            }
         }
    
         private void ProcessQueue(object sender, ElapsedEventArgs args)
         {
            try
            {
               Console.WriteLine("Processing queue, " + filePaths.Count + " files created:");
               rwlock.EnterReadLock();
               foreach (string filePath in filePaths)
               {
                  Console.WriteLine(filePath);
               }
               filePaths.Clear();
            }
            finally
            {
               if (processTimer != null)
               {
                  processTimer.Stop();
                  processTimer.Dispose();
                  processTimer = null;
               }
               rwlock.ExitReadLock();
            }
         }
    
         protected virtual void Dispose(bool disposing)
         {
            if (disposing)
            {
               if (rwlock != null)
               {
                  rwlock.Dispose();
                  rwlock = null;
               }
               if (watcher != null)
               {
                  watcher.EnableRaisingEvents = false;
                  watcher.Dispose();
                  watcher = null;
               }
            }
         }
    
         public void Dispose()
         {
            Dispose(true);
            GC.SuppressFinalize(this);
         }
    
      }     
    

    Remember to set the buffer size on your fswatcher AND implement "resurrection" of the fswatcher if it gets an error (i.e. bind the error event to a method that recreates the watcher).

    Edit: note, the timer in this example is a System.Timers.Timer, not a System.Threading.Timer

    Edit: Now contains error handling for the watcher, dispose logic.

提交回复
热议问题