2012-10-17 27 views
8

爲什麼FileSystemWatcher激發兩次?有沒有簡單的方法來解決它?當然,如果我更新或編輯文本文件,它應該只會觸發一次?爲什麼FileSystemWatcher激發兩次

此鏈接這裏http://weblogs.asp.net/ashben/archive/2003/10/14/31773.aspx

  1. 活動被兩次上調 - 事件將提高兩倍,如果事件處理程序(AddHander FSW.Created,AddressOf FSW_Created)是 明確指定。這是因爲默認情況下,公共事件 會自動調用相應的受保護方法(OnChanged, OnCreated,OnDeleted,OnRenamed)。要糾正這個問題,只需要刪除顯式事件處理程序(AddHandler ...)。

「刪除顯式事件處理程序」是什麼意思?

Imports System.IO 

Public Class Form2 

    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed 

     'this fires twice 
     MessageBox.Show("test") 

    End Sub 

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

     FileSystemWatcher1.Path = "C:\Users\c\Desktop\test\" 
     FileSystemWatcher1.NotifyFilter = NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName Or NotifyFilters.DirectoryName Or NotifyFilters.CreationTime 

     FileSystemWatcher1.IncludeSubdirectories = False 
     FileSystemWatcher1.Filter = "text.txt" 

    End Sub 

End Class 
+0

究竟您是否遇到此意外*行爲?是編輯文件,移動,刪除還是創建文件? – Arrow

+1

嗨編輯該文件是什麼時候發生的 - 謝謝 –

+0

我已經用可能的解決方案更新了我的問題,至少要檢查一下,因爲它可能有助於縮小問題的範圍。 – Arrow

回答

8

更新:

我已經想出了2個解決方案。一個使用線程,另一個不使用線程。請選擇:-)。

不必穿線:

Imports System.IO 

Public Class Form1 
    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed 
     Dim watcher As System.IO.FileSystemWatcher = sender 
     watcher.EnableRaisingEvents = False 

     'Do work here while new events are not being raised. 
     MessageBox.Show("Test") 

     watcher.EnableRaisingEvents = True 'Now we can begin watching for new events. 

    End Sub 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

     FileSystemWatcher1.Path = "C:\Users\c\Desktop\test" 
     FileSystemWatcher1.NotifyFilter = NotifyFilters.LastWrite 
     FileSystemWatcher1.IncludeSubdirectories = False 
     FileSystemWatcher1.Filter = "test.txt" 


    End Sub 

    Private Sub FileSystemWatcher_OnChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 

    End Sub 

End Class 

該解決方案(無螺紋),設置watcher.EnableRaisingEvents爲False。在此之後,您通常會處理任何受影響(或更改)的文件。然後在您的工作完成後,將EnableRaisingEvents設置回True。

隨着線程:

Imports System.IO 

Public Class Form1 
    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed 
     FileSystemWatcher1.EnableRaisingEvents = False 
     Threading.Thread.Sleep(250) 
     FileSystemWatcher1.EnableRaisingEvents = True 


     MessageBox.Show("test") 


    End Sub 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

     FileSystemWatcher1.Path = "C:\Users\c\Desktop\test" 
     FileSystemWatcher1.NotifyFilter = NotifyFilters.LastWrite 
     FileSystemWatcher1.IncludeSubdirectories = False 
     FileSystemWatcher1.Filter = "test.txt" 


    End Sub 

    Private Sub FileSystemWatcher_OnChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 

    End Sub 

End Class 

該解決方案,雖然有點哈克,確實工作。它會禁止檢查250ms的新更改/事件,然後重新啓用檢查,這是基於您不需要每250ms檢查一次更改的假設。我嘗試了幾乎所有我能想到的解決方案,但這同時會起作用。

+1

我已經看到過這種類型的解決方案以及其他Web上的帖子。它也適用於我。微軟在http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx上解釋它。 – JimDel

+0

謝謝。我剛剛找到了一個更合適,可行的解決方案,它非常相似,但它不需要使用線程。現在正在更新。 – Arrow

+0

謝謝,第一種技術爲我工作。我在一個小的Windows服務中使用'FileSystemWatcher',它正在編譯供LiveReload使用的樣式表,並且多個更改事件正在陷入瀏覽器中。但是這個小調整已經修復了[FUOC](http://www.bluerobot.com/web/css/fouc.asp/)問題。 ;) – harpo

1

檢查e.ChangeType。我想你會得到兩個不同的通知。也許LastAccess和LastModified。在這種情況下,這是預期的行爲。

+0

謝謝,但如果我把那些出來,它仍然會發生兩次 –

相關問題