2012-03-01 19 views
3

我有這樣一段代碼 我想插件的StartWatch()和OnFinalChanged()之間的同步,所以最終什麼將被打印出來將按照以下順序:如何同步FileSystemWatcher的

Creating plugin for file c:\temp\file1.txt 
Creating plugin for file c:\temp\file2.txt 
Creating plugin for file c:\temp\file3.txt 
Starting watching c:\temp\file1.txt 
Finished watching file c:\temp\file1.txt 
Starting watching c:\temp\file2.txt 
Finished watching file c:\temp\file2.txt 
Starting watching c:\temp\file3.txt 
Finished watching file c:\temp\file3.txt 
namespace Test2 
{ 
    internal static class MyProgram 
    { 
     [STAThread] 
     private static void Main(string[] args) 
     { 
      List<Plugin> plugins = new List<Plugin> 
             { 
              new Plugin(@"c:\temp\file1.txt"), 
              new Plugin(@"c:\temp\file2.txt"), 
              new Plugin(@"c:\temp\file3.txt"), 
             }; 

      foreach (var plugin in plugins) 
      { 
       // I need StartWatch to be called only after i got OnChanged() for the previous plugin 
       plugin.StartWatch(); 
      } 
     } 
    } 


    public class Plugin 
    { 
     private FileSystemWatcher _watcher; 
     private readonly string _file; 

     public Plugin(string file) 
     { 
      _file = file; 
      Console.WriteLine("Creating plugin for file {0}", _file); 
     } 

     public void StartWatch() 
     { 
      Console.WriteLine("Starting watching {0}", _file); 
      FileInfo fileInfo = new FileInfo(_file); 
      if (fileInfo.Directory != null) 
      { 
       _watcher = new FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name); 
       _watcher.NotifyFilter = NotifyFilters.LastWrite; 
       _watcher.Changed += OnChanged; 
       _watcher.EnableRaisingEvents = true; 
      } 
      // i want the main thread to be paused untill i get the OnChanged() 
     } 

     private void OnChanged(object source, FileSystemEventArgs e) 
     { 
      Console.WriteLine("Finished watching file {0}", _file); 
      _watcher.Dispose(); 

      // once i get this event, i want the main thread to continue and to start watching the same plugin 
     } 
    } 
} 
+0

當您運行此代碼時會發生什麼? – vulkanino 2012-03-01 14:41:12

回答

2

使用AutoResetEvent應該完成這項工作。

namespace Test2 
{ 
    internal static class MyProgram 
    { 
     [STAThread] 
     private static void Main(string[] args) 
     { 
      List<Plugin> plugins = new List<Plugin> 
             { 
              new Plugin(@"c:\temp\file1.txt"), 
              new Plugin(@"c:\temp\file2.txt"), 
              new Plugin(@"c:\temp\file3.txt"), 
             }; 

      foreach (var plugin in plugins) 
      { 
       // I need StartWatch to be called only after i got OnChanged() for the previous plugin 
       plugin.StartWatch(); 
       plugin.WaitHandler.WaitOne(); 
      } 
     } 
    } 


    public class Plugin 
    { 
     private FileSystemWatcher _watcher; 
     private readonly string _file; 
     public AutoResetEvent WaitHandler {get;private set;} 

     public Plugin(string file) 
     { 
      _file = file; 
      Console.WriteLine("Creating plugin for file {0}", _file); 
      WaitHandler = new AutoResetEvent(false); 
     } 

     public void StartWatch() 
     { 
      Console.WriteLine("Starting watching {0}", _file); 
      WaitHandler.Reset(); 
      FileInfo fileInfo = new FileInfo(_file); 
      if (fileInfo.Directory != null) 
      { 
       _watcher = new FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name); 
       _watcher.NotifyFilter = NotifyFilters.LastWrite; 
       _watcher.Changed += OnChanged; 
       _watcher.EnableRaisingEvents = true; 
      } 
      // i want the main thread to be paused untill i get the OnChanged() 
     } 

     private void OnChanged(object source, FileSystemEventArgs e) 
     { 
      Console.WriteLine("Finished watching file {0}", _file); 
      _watcher.Dispose(); 

      // once i get this event, i want the main thread to continue and to start watching the same plugin 
      WaitHandler.Set(); 
     } 
    } 
} 
+0

它似乎沒有工作,我複製/粘貼你的答案,它的行爲是相同的,我想它以我寫的相同的順序打印。我猜fileSystemWatcher使用了不同的線程... – user829174 2012-03-01 14:59:32

+0

你是否改變了foreach循環中的主要方法? – 2012-03-01 15:10:49

+0

你是對的,我也發現FileSystemWatcher有.WaitForChanged(WatcherChangeTypes.All),這也是做這項工作。 – user829174 2012-03-01 15:25:03