C# FileSystemWatcher WaitForChanged Method only de

2019-05-30 00:51发布

问题:

I got a problem similar to this one: FileSystemWatcher - only the change event once firing once?

But since that thread is two years old and my code is a bit different, I decided to open a new question.

Well, here's my code:

while (true)
{
  FileSystemWatcher fw = new FileSystemWatcher();

  fw.Path = @"Z:\";
  fw.Filter = "*.ini";
  fw.WaitForChanged(WatcherChangeTypes.All);
  Console.WriteLine("File changed, starting script...");
  //if cleanup
  try
  {
      if (File.ReadAllLines(@"Z:\file.ini")[2] == "cleanup")
      {
          Console.WriteLine("Cleaning up...");
          Process c = new Process();
          c.StartInfo.FileName = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop).Trim('\\') + @"\clean.exe";
          c.StartInfo.WorkingDirectory = System.Environment.SpecialFolder.DesktopDirectory.ToString();
          c.Start();
          c.WaitForExit();
          Console.WriteLine("Done with cleaning up, now starting script...");
      }
  }
  catch
  {
      Console.WriteLine("No cleanup parameter found.");
  }
  Process p = new Process();
  p.StartInfo.FileName = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop).Trim('\\') + @"\go.exe";
  p.StartInfo.WorkingDirectory = System.Environment.SpecialFolder.DesktopDirectory.ToString();
  p.Start();
  Console.WriteLine("Script running...");
  p.WaitForExit();
  fw = null;
  Console.WriteLine("Done. Waiting for next filechange...");
}

Problem: This program should detect a file change in the file "Z:\file.ini". If it has changed, a script should be fired. When the script is done, the programm should return to the start and start watching for changes, again (that's why I used the while-loop). Well, the first change is detected and everything seems to be working just fine, but any changes AFTER the first one are not going to be detected. I tried to set the FileSystemWatcher Object to null, as you can see, but it didn't help.

So, I hope for good answers. Thanks.

回答1:

I would change your design so you don't rely on the FileSystemWatcher for any changes. Instead poll the directory or the file that your watching for any changes. You can then use the FileSystemWatcher in conjunction with this to wake it up as soon as possible if we know there are changes. This way, if you miss an event, you'd still recover from it based on your poll time-out.

e.g.

static void Main(string[] args)
{
    FileSystemWatcher watcher = new FileSystemWatcher(@"f:\");
    ManualResetEvent workToDo = new ManualResetEvent(false);
    watcher.NotifyFilter = NotifyFilters.LastWrite;
    watcher.Changed += (source, e) => { workToDo.Set(); };
    watcher.Created += (source, e) => { workToDo.Set(); };

    // begin watching
    watcher.EnableRaisingEvents = true;

    while (true)
    {
        if (workToDo.WaitOne())
        {
            workToDo.Reset();
            Console.WriteLine("Woken up, something has changed.");
        }
        else
            Console.WriteLine("Timed-out, check if there is any file changed anyway, in case we missed a signal");

        foreach (var file in Directory.EnumerateFiles(@"f:\")) 
            Console.WriteLine("Do your work here");
    }
}