2012-03-29 20 views
1

感謝所有幫助這個..FileSystemWatcher的線程上

我試圖寫一個小程序FileWatcher監視本地目錄和副本跨越到另一個本地目錄中的任何改變。我在.Net中使用了FileSystemWatcher類,在我的btnStart中單擊我運行四個線程,每個線程都有自己的FileSysWatcher實例,用於監視不同的更改類型。所以我想要尋找的第一個是創建的事件。

new Thread(Created).Start(); 

那麼我:

void Created() 
{ 
    FileSystemWatcher Watcher2 = new FileSystemWatcher(); 

    Watcher2.Path = txtBxDirToWatch.Text; 
    Watcher2.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.DirectoryName; 

    //watch all files in the path 

    Watcher2.Filter = "*.*"; 

    //dont watch sub dir as default 
    Watcher2.IncludeSubdirectories = false; 
    if (chkBxIncSub.Checked) 
    { 
     Watcher2.IncludeSubdirectories = true; 
    } 

    Watcher2.Created += new FileSystemEventHandler(OnCreated); 
    Watcher2.EnableRaisingEvents = true; 
} 

所有我想這個做的就是複製到一個硬編碼的本地路徑的任何變化,但我不能得到任何結果。這裏是我處理事件的地方

public static void OnCreated(object source, FileSystemEventArgs e) 
{ 
    //combine new path into a string 
    string created = Path.Combine(@"C:\WatcherChanges", e.Name); 
    File.Create(created); 
} 
+1

您是否嘗試調試它?你的OnCreated是否被打到,然後你創建文件?你確定e.Name是一個文件名,而不是完整的文件路徑嗎? – Nikolay 2012-03-29 06:05:10

+1

檢查是否創建了此新線程,因爲您正在從新線程訪問UI控件。我相信這是拋出異常,你沒有看到它。 – Marcin 2012-03-29 06:15:12

回答

0

在你的代碼線程完成後,然後GC收集並釋放Watcher。

不要使用線程觀察家或「掛起」線程:

new Thread(Created){IsBackground = true}.Start(); 

void Created() 
{ 
    ... 

    Thread.CurrentThread.Join(); 
} 
0

你的線程退出你告訴觀察者,使引發事件之後。 Create方法中沒有任何內容保持線程運行。在Create方法結束時,FileSystemWatcher超出範圍,線程退出。它永遠不會看到任何事件。

有很多方法可以讓線程等待。這是一個簡單的。

public class Watcher 
{ 
    private ManualResetEvent resetEvent = new ManualResetEvent(false); 

    public ManualResetEvent ResetEvent { get { return resetEvent; } 

    void Created() 
    { 
     FileSystemWatcher Watcher2 = new FileSystemWatcher(); 

     Watcher2.Path = txtBxDirToWatch.Text; 
     Watcher2.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.DirectoryName; 

     //watch all files in the path 

     Watcher2.Filter = "*.*"; 

     //dont watch sub dir as default 
     Watcher2.IncludeSubdirectories = false; 
     if (chkBxIncSub.Checked) 
     { 
      Watcher2.IncludeSubdirectories = true; 
     } 

     Watcher2.Created += new FileSystemEventHandler(OnCreated); 
     Watcher2.EnableRaisingEvents = true; 

     resetEvent.WaitOne(); 
    } 

然後更改來電Thread.Start喜歡的東西

Watcher watcher = new Watcher(); 
new Thread(watcher.Created).Start(); 

的方法,當你想停止觀看

watcher.ResetEvent.Set(); 

你看着RoboCopy?它會爲你做到這一點。

0

沒有理由在單獨的線程中創建觀察者。

當您觀看的目錄發生某些事情時,他們會回到thread pool線程。當他們這樣做 - 你在線程池線程上做你的工作,如果它不是UI相關的。如果是 - 你必須做control.Invoke或使用SynchronizationContext發佈/發送到Gui線程。

是的 - 正如其他人已經說過的 - 不要讓你的觀察者得到GC'd。