2014-01-08 262 views
4

我就需要使用FileSystemWatcher類,以便創建新文件時它會通知C#程序的工作。作爲初始化的一部分,程序掃描目錄,以便它可以處理其中已有的任何文件。這一切工作正常。FileSystemWatcher的陷阱

然而,與其他開發者的討論,我們開始質疑這是否就沒有問題。有沒有條件下FileSystemWatcher將錯過創建文件?如果是這樣,這些條件是什麼?

爲了處理這種情況,我們只是在我們的初始化過程中運行代碼,以定期掃描目錄,但FileSystemWatcher錯過文件的可能性有多大?

+0

這個以前的問題/答案應該給你一個好的開始:http:/ /stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes。簡而言之,FileSystemWatcher底層的Win32緩衝區可能會溢出 – Kevin

+1

[.NETFramwork 4中的FileSystemWatcher的可靠程度如何?](http://stackoverflow.com/questions/7191380/how-reliable-is-the-filesystemwatcher-in -netframwork-4) – Yuck

回答

11

FileSystemWatcher將不會通常未中的文件。但是:

  • ,因爲它是基於ReadDirectoryChangesW,它只能檢測更改該文件的目錄項,不更改文件本身。文件的大部分更改都會更新目錄條目,但有一些例外(請參閱this article)。
  • 文件更改通知的緩衝區大小有限;如果您沒有足夠快地處理事件,緩衝區將溢出,導致您錯過事件。這就是爲什麼你不應該在事件處理程序中做任何重大處理的原因。如果您無法快速處理事件,只需將它們添加到您在另一個線程上處理的隊列即可。

其他陷阱:

  • 的通知不立即到達;實際更改和通知之間的延遲通常很短,但我已經看到它延長到幾秒鐘。這對大多數用例來說不是主要問題,但取決於你想要做什麼,這可能是一個問題。
  • 沒有爲Moved沒有事件。如果將文件從目錄移動到另一個目錄,您將收到兩個通知:DeletedCreated
  • 有時,根據卷配置,通知中的路徑可能是舊的8.3格式(例如,您可以獲得SOMETH~1.TXT而不是的Something.txt
  • 如果移動現有的,非空目錄到監控目錄,你只會得到目錄本身,而不是它的內容的通知。您需要手動檢查內容。
  • Changed事件可以發生多次爲同一文件;你需要自己處理重複的東西
+0

感謝您的詳細回覆。我們已經知道多個更改事件和移動陷阱。我已閱讀過有關今天早些時候移動非空目錄的問題。我不知道目錄條目與文件本身的問題。幸運的是,我只對添加新文件感興趣,而不是對現有文件的更改。再次感謝! –

2

FileSystemWatcher是不應該錯過任何文件,但是,如果你的文件處理很長,你應該隊列中的事件,並在不同的線程對待他們。

0

我已經使用了fs watcher時間,FSwatcher創建事件觸發器時創建的最大挑戰(沒有實際的最終大小),這意味着如果有人插入在文件共享中創建了一個巨大的文件「gigs」,它將被鎖定,直到創建者應用程序發佈的文件,這樣我才能在測試環境中看到完美的效果,在這種環境中可以顯示有限的文件和數據。對於生產fswatcher結合後臺工作人員和定時器可以成爲解決方案,例如FSwatcher創建的甚至應該將任務交給後臺工作人員。儘管如此,我還是看到了一些我需要每小時計時器來移動剩餘文件的情況,當用戶在幾個小時內仍在使用這些文件時,出現了一些奇怪的情況。我發現完美的解決方案使用FSwatcher以及多線程和定時器。我假設你想要一個Windows服務,而不是基於表單或基於Web的應用程序。對於文件更改的事件,我不會使用這個,如果任何應用程序在文件流中打開文件,它將執行幾個更改,但仍然鎖定文件,所以你可以不做任何事情,也許你可以添加到列表,以便能夠稍後處理它,但據我所知,在這種情況下,如果文件在流中被編輯,它將繼續激發你的事件。所以我的建議使用創建的事件在事件中設置了一些超時來檢查真正的快速讀取可用性,如5秒,如果這沒有發生後臺線程,甚至bg踩仍然不能處理該文件,有一個計時器保持重試在所有文件中,這兩種情況下都沒有處理(像大文件和服務終止,然後處理後臺線程)。

概要FSwatcher引發事件,但並不意味着文件可以被訪問和準備處理,它只是監視文件系統並激發你訂閱的事件。事件觸發,但如果你沒有足夠快地處理它,你可能會錯過下一個事件,所以使用事件進行非常快速的動作,如果你創建了很多文件,比如將它們添加到列表中,任務!如果你在一個事件中花費太多時間,你可能會錯過一些,所以趕上事件,立即交接任務,並等待下一個:)