2012-10-17 35 views
8

tại sao FileSystemWatcher lại kích hoạt hai lần? Có cách nào dễ dàng để sửa chữa nó? Chắc chắn nếu tôi cập nhật hoặc chỉnh sửa các tập tin văn bản nó chỉ nên cháy một lần?Tại sao FileSystemWatcher lại kích hoạt hai lần

liên kết này đây http://weblogs.asp.net/ashben/archive/2003/10/14/31773.aspx nói

  1. Sự kiện được nâng lên gấp đôi - Một sự kiện sẽ được nâng lên gấp đôi nếu một event handler (AddHander FSW.Created, AddressOf FSW_Created) là quy định một cách rõ ràng. Điều này là do, theo mặc định, các sự kiện công khai sẽ tự động gọi các phương thức được bảo vệ tương ứng (OnChanged, OnCreated, OnDeleted, OnRenamed). Để khắc phục sự cố này, chỉ cần xóa trình xử lý sự kiện rõ ràng (AddHandler ...).

"Xóa trình xử lý sự kiện rõ ràng" có nghĩa là gì?

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

Khi nào chính xác bạn đang gặp phải hành vi * không mong muốn này? Có phải khi bạn chỉnh sửa tệp, di chuyển, xóa hoặc tạo tệp không? – Arrow

+1

hi chỉnh sửa tập tin là khi nó xảy ra - cảm ơn –

+0

Tôi đã cập nhật câu hỏi của mình với một giải pháp khả thi, ít nhất một điều gì đó để kiểm tra vì nó có thể giúp thu hẹp vấn đề. – Arrow

Trả lời

8

Cập nhật:

Tôi đã đưa ra 2 giải pháp. Một sử dụng Threads, và cái kia thì không. Bạn chọn đi :-).

Nếu không có luồng:

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 

Giải pháp này (không có luồng), đặt watcher.EnableRaisingEvents False. Đó là sau thời điểm này, nơi bạn thường sẽ xử lý bất kỳ tập tin bị ảnh hưởng (hoặc thay đổi). Sau đó nó đặt EnableRaisingEvents trở lại True sau khi công việc của bạn được thực hiện.

Với luồng:

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 

giải pháp này, mặc dù một chút hacky, làm việc. Nó vô hiệu hóa việc kiểm tra các thay đổi/sự kiện mới cho 250ms và sau đó kích hoạt lại kiểm tra, dựa trên giả định rằng bạn sẽ không cần phải kiểm tra thay đổi mỗi 250ms. Tôi đã thử gần như tất cả mọi thứ mà tôi có thể nghĩ ra để có được một giải pháp thực sự cho bạn nhưng điều này sẽ làm việc trong thời gian chờ đợi.

+1

Tôi đã thấy loại giải pháp này được sử dụng trước đây trong các bài đăng khác trên web. Nó cũng làm việc tốt cho tôi.Microsoft Giải thích nó trên http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx – JimDel

+0

Cảm ơn bạn. Tôi vừa tìm thấy một giải pháp phù hợp, khả thi hơn rất giống, mặc dù nó không yêu cầu sử dụng các luồng. Đang cập nhật ngay bây giờ. – Arrow

+0

Cảm ơn, kỹ thuật đầu tiên đã làm việc cho tôi. Tôi đã sử dụng 'FileSystemWatcher' trong một dịch vụ Windows nhỏ đang biên soạn các bảng định kiểu để sử dụng bởi LiveReload và các sự kiện thay đổi nhiều đang làm giảm trình duyệt. Nhưng điều chỉnh nhỏ này đã sửa lỗi [FUOC] (http://www.bluerobot.com/web/css/fouc.asp/) -ing. ;) – harpo

1

Kiểm tra e.ChangeType. Tôi tưởng tượng bạn đang nhận được hai thông báo khác nhau. Có lẽ LastAccess và LastModified. Trong trường hợp đó, đó là hành vi mong đợi.

+0

cảm ơn nhưng nếu tôi lấy chúng ra thì nó vẫn cháy hai lần –

Các vấn đề liên quan