2012-10-17 20 views
8

perché il FileSystemWatcher viene attivato due volte? C'è un modo semplice per risolverlo? Sicuramente se aggiorno o modifico il file di testo dovrebbe sparare solo una volta?Perché FileSystemWatcher viene attivato due volte

questo link qui http://weblogs.asp.net/ashben/archive/2003/10/14/31773.aspx dice

  1. Eventi a salire due volte - Un evento sarà sollevato due volte se un gestore di eventi (AddHander FSW.Created, AddressOf FSW_Created) è espressamente specificato. Questo perché, per impostazione predefinita, gli eventi pubblici chiamano automaticamente i rispettivi metodi protetti (OnChanged, OnCreated, OnDeleted, OnRenamed). Per correggere questo problema, semplicemente rimuovere il gestore eventi esplicito (AddHandler ...).

Che cosa significa "rimuovere il gestore di eventi espliciti"?

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

Quando si verifica esattamente questo comportamento * inaspettato *? È quando si modifica un file, si sposta, si elimina o si crea un file? – Arrow

+1

hi edit il file è quando succede - grazie –

+0

Ho aggiornato la mia domanda con una possibile soluzione, almeno qualcosa da verificare in quanto potrebbe aiutare a restringere il problema. – Arrow

risposta

8

Aggiornamento:

Sono venuto con 2 soluzioni. Uno usa Thread e l'altro no. Fai la tua scelta :-).

Senza filettatura:

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 

Questa soluzione (senza filettatura), imposta i watcher.EnableRaisingEvents False. È dopo questo punto in cui normalmente si elaborano i file interessati (o modificati). Quindi imposta EnableRaisingEvents su True dopo che il lavoro è terminato.

con filettatura:

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 

Questa soluzione, anche se un po 'hacky , funziona. Disabilita il controllo di nuove modifiche/eventi per 250 ms e quindi riabilita il controllo, in base al presupposto che non sarà necessario verificare una modifica ogni 250 ms. Ho provato quasi tutto quello che potevo pensare per ottenere una soluzione reale per te, ma questo funzionerà nel frattempo.

+1

Ho visto questo tipo di soluzione utilizzata anche in altri post sul Web. Ha funzionato bene anche per me.Microsoft Lo spiega su http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx – JimDel

+0

Grazie. Ho appena trovato una soluzione più adatta e praticabile che è molto simile, anche se non richiede l'uso di thread. Sto aggiornando ora. – Arrow

+0

Grazie, la prima tecnica ha funzionato per me. Stavo usando 'FileSystemWatcher' in un piccolo servizio di Windows che stava compilando i fogli di stile per l'uso da parte di LiveReload, e gli eventi con più modifiche stavano impantanando il browser. Ma questo piccolo aggiustamento ha risolto il problema [FUOC] (http://www.bluerobot.com/web/css/fouc.asp/) -ing. ;) – harpo

1

Controllare e.ChangeType. Immagino che ricevi due notifiche diverse. Forse LastAccess e LastModified. In tal caso, questo è il comportamento previsto.

+0

grazie, ma se li tengo fuori, spara ancora due volte –

Problemi correlati