2012-10-17 32 views
8

FileSystemWatcher neden iki kez ateş ediyor? Bunu düzeltmenin kolay bir yolu var mı? Elbette metin dosyasını günceller veya değiştirirsem sadece bir kez ateş etmeli?FileSystemWatcher neden iki kez yanıyor

bu bağlantı burada http://weblogs.asp.net/ashben/archive/2003/10/14/31773.aspx

  1. Olaylar iki kez gündeme getirilen diyor - bir olay işleyicisi (AddHander FSW.Created, AddressOf FSW_Created) açıkça belirtilmiş ise bir olay iki kez yükseltilir. Bunun nedeni, varsayılan olarak, genel olayları otomatik olarak ilgili korunan yöntemleri çağırır (OnChanged, OnCreated, OnDeleted, OnRenamed). Bu sorunu düzeltmek için, yalnızca açık olay işleyicisini kaldırın (AddHandler ...).

"Açık olay işleyicisini kaldırma" ne anlama geliyor?

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

Tam olarak ne zaman * beklenmedik * davranıyorsunuz? Bir dosyayı düzenlediğinizde, taşıdığınızda, sildiğinizde veya bir dosya oluşturduğunuzda mı? – Arrow

+1

Merhaba, dosyayı ne zaman olur - teşekkürler –

+0

Sorunu, sorunu daraltmaya yardımcı olabileceğinden emin olmak için en azından kontrol edilmesi gereken bir çözümle güncelledim. – Arrow

cevap

8

Güncelleme: Ben 2 çözümler gelmiş

. Biri Threads kullanıyor, diğeri de yapmıyor. İstediğini al :-). parçacığı olmadan

:

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 

Bu çözüm (diş olmadan), False watcher.EnableRaisingEvents ayarlar. Normalde hangi dosyaların etkilendiğini (veya değiştirildiğini) işleyeceğiniz bu noktadan sonra gelir. Sonra işiniz bittikten sonra EnableRaisingEvents değerini True olarak geri yükler. parçacığı ile

:

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 

Bu çözüm, biraz hacky rağmen çalışır. 250 ms için yeni değişiklikleri/olayları kontrol etmeyi devre dışı bırakır ve daha sonra her 250 ms'de bir değişiklik olup olmadığını kontrol etmeniz gerekmediği varsayımına dayanarak kontrolü yeniden etkinleştirir. Senin için gerçek bir çözüm bulmayı düşünebildiğim neredeyse herşeyi denedim ama bu arada işe yarayacak.

+1

Web'in etrafındaki diğer yazılarda da kullanılan bu tür bir çözümü gördüm. Benim için de iyi çalıştı.Microsoft bunu http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx – JimDel

+0

adresinden açıklar. Teşekkür ederiz. İplik kullanımını gerektirmese de, çok benzer, daha uygun, uygulanabilir bir çözüm buldum. Şimdi güncelleniyor. – Arrow

+0

Teşekkürler, ilk teknik benim için çalıştı. LiveReload tarafından kullanılacak stil sayfalarını derleyen küçük bir Windows hizmetinde 'FileSystemWatcher' kullanıyordum ve birden çok değişiklik olayı tarayıcıdan bogging yapıyordu. Ancak bu küçük ayar [FUOC] (http://www.bluerobot.com/web/css/fouc.asp/) -ing problemini çözmüştür. ;) – harpo

1

e.ChangeType öğesini kontrol edin. İki farklı bildirim aldığınızı hayal ediyorum. Belki de LastAccess ve LastModified. Bu durumda beklenen davranış budur.

+0

teşekkürler, ancak bunları çıkarırsam iki kez ateşlenir –