2009-10-15 31 views
6

FileSystemWatcher對象無法正常使用被添加到目錄FileSystemWatcher對象無法正常使用......當許多文件在同一時間,當許多文件添加到在同一時間目錄

看守人根本不找到目錄中的所有文件 - 只有當文件一個接一個地放入文件夾中時 - 並非在同一時間將大量文件複製到文件夾中...

是否創建了線程解決方案問題還是有另一種解決問題的方法?

+1

請記住,FileSystemWatcher依靠操作系統發出信號,當文件被添加/修改/刪除/等。所以有多個實例是不會有幫助的。 – 2009-10-15 13:46:37

回答

11

documentation on that class細節問題:

Windows操作系統通知您的文件更改組件由FileSystemWatcher的創建一個緩衝區。如果短時間內有很多變化,緩衝區可能會溢出。這會導致組件無法跟蹤目錄中的更改,並且只會提供一攬子通知。使用InternalBufferSize屬性來增加緩衝區的大小非常昂貴,因爲它來自無法換出到磁盤的非分頁內存,因此請將緩衝區保持爲小但足夠大以便不會錯過任何文件更改事件。爲避免緩衝區溢出,請使用NotifyFilterIncludeSubdirectories屬性,以便過濾掉不需要的更改通知。

因此,在這種情況下,線程可能無法幫到您。您可能想要增加緩衝區大小(但應該多大取決於計算機和磁盤本身的速度),或者通過設置適當的過濾器來限制您感興趣的文件。

+1

而且,當然,另一種選擇是另外輪詢該文件夾以找出錯過的新文件和文件。 – 2009-10-15 14:05:35

+0

我有時會低估C#,.Net等,因爲微軟世界中的開發很容易(通過說「微軟應該也認爲對我來說......」)並表現自大,所以不要閱讀文檔,然後把小時放入小東西像這一個大聲笑 – sotn 2017-02-01 13:50:34

0

嘗試這樣的事情。

public MainWindow() 
    { 
     InitializeComponent(); 

     #region initialise FileSystemWatcher 
     FileSystemWatcher watch = new FileSystemWatcher(); 
     watch.Path = folder; 
     watch.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName; 
     watch.Filter = ext; 
     watch.Changed += new FileSystemEventHandler(OnChanged); 
     watch.Created += new FileSystemEventHandler(OnChanged); 
     watch.EnableRaisingEvents = true; 
     #endregion 

    } 

private void OnChanged(object source, FileSystemEventArgs e) 
    { 
     Application.Current.Dispatcher.BeginInvoke((Action)delegate 
     { 
      // do your work here. If this work needs more time than it can be processed, not the filesystembuffer overflows but your application will block. In this case try to improve performance here. 
     }, System.Windows.Threading.DispatcherPriority.Normal); 
    } 
1

C#對我來說是新的,我在近一週的時間裏也遇到了同樣的麻煩。我有這個:

private void btnWatchFile_Click(object sender, EventArgs e) 
    { 
     //code to create a watcher and allow it to reise events... 
    } 

    //watcher onCreate event 
    public void onCreated(object sender, FileSystemEventArgs e) 
    { 
     if (!updateNotifications) 
     { 
      stringBuilder.Remove(0, stringBuilder.Length); 
      stringBuilder.Append(e.FullPath); 
      stringBuilder.Append(" "); 
      stringBuilder.Append(e.ChangeType.ToString()); 
      stringBuilder.Append(" "); 
      stringBuilder.Append(DateTime.Now.ToString()); 
      updateNotifications = true; 
     } 
    } 

    //timer to check the flag every X time 
    private void timer_Tick(object sender, EventArgs e) 
    { 
     if (updateNotifications) 
     { 
      notificationListBox.Items.Insert(0, stringBuilder.ToString()); 
      updateNotifications = false; 
     } 
    } 

我甚至將計時器間隔設置爲1毫秒,但一些新的文件事件丟失。我試圖從onCreated事件中更新notificationsListBox,但我總是收到交叉引用錯誤。直到我發現觀察者onCreated事件在主要方法線程之外的線程中執行,因此,在堅果殼中,這是我的解決方案:

我包含public delegate void Action()作爲我的屬性然後使用Invoke更新onCreated事件中的notificationsListBox。接下來,片段代碼:

public void onCreated(object sender, FileSystemEventArgs e) 
    { 
     stringBuilder.Remove(0, stringBuilder.Length); 
     stringBuilder.Append(e.FullPath); 
     stringBuilder.Append(" "); 
     stringBuilder.Append(e.ChangeType.ToString()); 
     stringBuilder.Append(" "); 
     stringBuilder.Append(DateTime.Now.ToString()); 
     updateNotifications = true; 
     Invoke((Action)(() => {notificationListBox.Items.Insert(0, stringBuilder.ToString());})); 
    } 

因此,計時器及其代碼不再需要。 這對我來說非常適用,我希望它適用於任何有類似情況的人。 祝你好運!

相關問題