2010-07-14 44 views
13

Tôi đang viết một công cụ giám sát thư mục mạng và đang tắt máy Windows Server 2008, sự kiện OnChanged cho FileSystemWatcher đang được kích hoạt chính xác từ các tệp được đặt trên ổ đĩa mạng bởi bất kỳ máy tính nào không sử dụng Windows 7, vì một số lý do nếu số lượng tệp được sao chép lớn hơn 19 trên máy tính Windows 7 (cùng một lúc) thì không có sự kiện nào được kích hoạt mặc dù nó hoạt động nếu tệp được thực hiện riêng lẻ. Có một cách giải quyết cho điều này hoặc là chỉ làm thế nào hạt nhân Windows 7 cư xử với các sự kiện FSW?FileSystemWatcher và windows 7

Chỉ cần làm rõ nó hoạt động cho hàng nghìn tệp khi được sao chép từ máy XP. (Phần mềm vẫn còn trên máy chủ 2008).

Trả lời

22

Từ MSDN:

Các hệ điều hành Windows thông báo cho thành phần của bạn thay đổi tập tin trong một bộ đệm tạo ra bởi các FileSystemWatcher. Nếu có nhiều thay đổi trong một thời gian ngắn, bộ đệm có thể tràn. Điều này làm cho thành phần mất theo dõi các thay đổi trong thư mục và nó sẽ chỉ cung cấp thông báo chăn. Tăng kích thước của bộ đệm với thuộc tính InternalBufferSize là tốn kém, vì nó đến từ bộ nhớ không phân trang mà không thể được hoán đổi ra đĩa, vì vậy giữ bộ đệm nhỏ nhưng đủ lớn để không bỏ lỡ bất kỳ sự kiện thay đổi tệp nào. Để tránh tràn bộ đệm, hãy sử dụng các thuộc tính NotifyFilterIncludeSubdirectories để bạn có thể lọc ra các thông báo thay đổi không mong muốn.

Nếu tăng dung lượng bộ đệm không đủ và bạn không thể kiểm soát số lượng tệp đang kích hoạt sự kiện tại thời điểm bạn sẽ phải thêm bỏ phiếu bổ sung.

cũng Xem câu hỏi liên quan này:

FileSystemWatcher does not work properly when many files are added to the directory at the same time…

Cập nhật:

Nó có thể là hấp dẫn để đơn giản là tăng kích thước bộ đệm nhưng điều này nên được thực hiện một cách cẩn thận. Trong thực tế, có một giới hạn 64k khi nói đến truy cập mạng. Lớp FileSystemWatcher đang sử dụng chức năng Windows API ReadDirectoryChangesW bên dưới trong đó có giới hạn này:

ReadDirectoryChangesW không thành công với ERROR_INVALID_PARAMETER khi chiều dài đệm lớn hơn 64 KB và ứng dụng được giám sát một thư mục trên mạng. Điều này là do giới hạn kích thước gói với các giao thức chia sẻ tệp cơ bản.

Nếu bạn muốn nhận được một sự hiểu biết sâu sắc hơn về chi phí của việc sửa đổi kích thước bộ đệm, bạn nên có một cái nhìn tại các bài viết của Walter Wang của Microsoft ở đây:

FileSystemWatcher across the network (đầy đủ bài trích dẫn bên dưới)

Tôi xin lỗi vì tài liệu của FileSystemWatcher.InternalBufferSize không nêu rõ về kích thước bộ đệm khi giám sát mạng đường dẫn. Bạn không nên vượt quá 64K khi giám sát đường dẫn mạng.

FileSystemWatcher về cơ bản là a.Net trình bao bọc cho Win32 API ReadDirectoryChangesW. Để sử dụng ReadDirectoryChangesW, bạn tạo và chỉ định bộ đệm mà Hệ điều hành sẽ điền với các thay đổi. Tuy nhiên, những gì không được đề cập trong tài liệu ReadDirectoryChangesW (nhưng được gợi ý trong docs FileSystemWatcher) là hệ thống tập tin tạo ra một hạt nhân nội đệm để lưu trữ các thông tin thay đổi tạm thời cho đến khi nó có cơ hội để cập nhật bộ đệm người dùng. Kích thước của bộ đệm hạt nhân được tạo ra là cùng kích thước được chỉ định trong ReadDirectoryChangesW và được tạo ra trong bộ nhớ không phân trang gộp. Mỗi lần một FileSystemWatcher/ ReadDirectoryChangesW được tạo/ được gọi, bộ đệm hạt nhân mới cũng được tạo .

Các nhóm bộ nhớ hạt nhân (được phân trang và không phân trang) được đặt sang một bên trong không gian địa chỉ dành cho trình điều khiển thiết bị và các thành phần hạt nhân khác để sử dụng. Họ phát triển và thu nhỏ động như cần thiết. Bạn có thể dễ dàng nhìn thấy kích thước hiện tại của các hồ bơi bằng cách đi tới tab Hiệu suất của Trình quản lý Tác vụ . Các hồ bơi sẽ tăng trưởng động cho đến khi chúng đạt đến giá trị tối đa được tính tại thời điểm khởi động và phụ thuộc vào hệ thống có sẵn tài nguyên (chủ yếu là RAM). Bạn không muốn đạt giá trị tối đa này hoặc khác các dịch vụ và trình điều khiển hệ thống khác nhau sẽ bắt đầu không thành công. Tuy nhiên, điều này giá trị tối đa được tính không phải là dễ dàng có sẵn. Để xác định kích thước hồ bơi tối đa , bạn cần sử dụng trình gỡ lỗi hạt nhân . Nếu bạn quan tâm đến thông tin thêm về hệ thống hồ bơi bộ nhớ, tôi khuyên bạn nên xem Chương 7 trong sách MSPress Bên trong Windows 2000 của Solomon và Russinovich.

Với ý nghĩ này, không có đề xuất về bộ đệm kích thước mà bạn có thể sử dụng. Kích thước hiện tại và tối đa của các hồ bơi hệ thống sẽ là được thay đổi từ khách hàng đến ứng dụng khách. Tuy nhiên, có thể bạn không nên đi trên 64k cho mỗi bộ đệm FileSystemWatcher/ ReadDirectoryChangesW. Điều này bắt nguồn từ thực tế là có giới hạn64k có quyền truy cập mạng là được ghi lại trong ReadDirectoryChangesW. Nhưng cuối cùng, bạn sẽ có để kiểm tra ứng dụng trên nhiều loại của các hệ thống đích được mong đợi để bạn có thể điều chỉnh bộ đệm của bạn.

Có overhead kết hợp với các ứng dụng Net và tôi tưởng tượng rằng một chương trình Win32 ReadDirectoryChangesW có thể có thể đạt được tốt hơn hiệu suất với các kích thước bộ đệm tương tự. Tuy nhiên, với những thay đổi tập tin rất nhanh và nhiều, vượt đệm sẽ không thể tránh khỏi và các nhà phát triển đang diễn ra phải xử lý các trường hợp khi một tràn ngập xảy ra như tay liệt kê các thư mục để phát hiện những thay đổi .

Tóm lại, FileSystemWatcher và ReadDirectoryChangesW là một nhẹ phát hiện sự thay đổi tập tin cơ chế có nghĩa là sẽ có hạn chế của nó. Thay đổi tạp chí là một cơ chế mà chúng tôi sẽ xem xét một giải pháp vừa cân, nhưng vẫn sẽ có những hạn chế:

http://msdn.microsoft.com/en-us/library/aa363798%28VS.85%29.aspx

giải pháp nặng trọng lượng sẽ được viết lái xe một bộ lọc hệ thống tập tin chuyên dụng nằm trong hệ thống tập tin ngăn xếp và giám sát hệ thống tập tin thay đổi. Tất nhiên đây sẽ là cách tiếp cận phức tạp nhất . Hầu hết các máy quét vi-rút , phần mềm sao lưu và tệp các tiện ích giám sát hệ thống như filemon (www.sysinternals.com) thực hiện trình điều khiển bộ lọc.

Tôi hy vọng giải thích ở trên sẽ giúp bạn hiểu nguyên nhân gốc của sự cố bạn đang gặp phải. Vui lòng trả lời cho chúng tôi biết bạn có cần thông tin thêm hay không. Cảm ơn bạn.

+0

Chỉ cần một bổ sung nhỏ: kích thước bộ đệm mặc định là 8192. –

4

Sau nhiều lần thử sử dụng FileSystemWatcher tôi đã từ bỏ nó. Nó sẽ không kích hoạt các sự kiện một cách chính xác, vào thời điểm sai, loại không chính xác. Thành thật mà nói tôi nghĩ rằng đó là một trong những lớp tồi tệ nhất trong khuôn khổ .net. Tôi đã luôn luôn kết thúc bằng văn bản lớp học của riêng tôi có một System.Timer và sau khi x mili giây trôi qua nó sẽ kiểm tra thư mục, tập tin bằng tay. Có phải mất nhiều công việc hơn và có thể nó là một PITA nhẹ nhưng một khi bạn đã viết nó, bạn có thể sử dụng nó bất cứ nơi nào bạn muốn. Tôi muốn FileSystemWatcher làm việc như quảng cáo nhưng tôi chưa bao giờ tìm thấy nó để làm như vậy.

+0

Tôi đồng ý rằng 'FileSystemWatcher' rõ ràng là không phù hợp trong mọi tình huống. Tuy nhiên, một khả năng mà nó cung cấp mà là khó khăn để làm với một liệt kê thư mục đơn giản là phát hiện tên tập tin. Nó có thể được thực hiện (bằng cách sử dụng so sánh tài sản tập tin, heuristics, MD5 khoản tiền, vv), nhưng nó là một rắc rối. – stakx

+0

@stakx, điều đó rất đúng, tôi chưa bao giờ thử kiểm tra thay đổi tên tệp. Tôi vừa bị đốt cháy bởi lớp học đó mà tôi chưa bao giờ sử dụng nó. – Justin

2

Hầu hết các lần khi sự kiện FileSystemWatcher kích hoạt, tôi bỏ qua các tệp đang được đối tượng truyền bởi vì danh sách này có thể không đầy đủ.

Tôi chỉ cần thu thập thông tin qua thư mục mà đối tượng FileSystemWatcher đang theo dõi và thực hiện quét thủ công để tìm các tệp có thể không nằm trong bộ đệm FileSystemWatcher. Nó không thực sự thanh lịch, nhưng nó chắc chắn rằng bạn sẽ không bỏ lỡ một tập tin.

+0

có vẻ như là một vấn đề hoàn toàn riêng biệt với sự không nhất quán mà OP đang nói đến. – Chad

+0

@Chad: Làm thế nào dường như điều này hoàn toàn không liên quan? Tôi sẽ nói nó âm thanh chính xác như một phương pháp để làm việc xung quanh vấn đề của OP. –

+0

vì OP nói rằng sự kiện đó không hề xảy ra. Laurens cho rằng * khi sự kiện cháy * họ tự kiểm tra thư mục, nhưng nếu sự kiện không bao giờ cháy ở nơi đầu tiên OP không thể làm điều này. Vì vậy, Laurens bình luận không phải là về cùng một vấn đề mà OP đang nhìn thấy. Ít nhất, đó là cách tôi đọc câu hỏi của OP liên quan đến bình luận của Laurens. – Chad

0

Đây là một lớp không đáng tin cậy, khi tệp ở trên ngưỡng nhất định, tôi đã có sự kiện kích hoạt khoảng 7 lần trên bản sao ban đầu và sau đó khi hộp thoại truyền tệp được thực hiện, tôi nhận được 7 sự kiện khác. tất cả các HĐH hỗ trợ FSW. Mặc dù Windows 7 (chưa thử vista) vẫn chỉ chấp nhận các tập tin một hoặc 19 tại một thời điểm trong khi nếu tôi thả các tập tin từ máy XP vào ổ đĩa mạng, tôi có thể đọc hàng ngàn tập tin cùng một lúc mà không có vấn đề gì. Điều này có thể chỉ là một thay đổi để ReadDirectoryChangesW từ XP đến 7. Quá 19 tập tin tôi không thể nhận được bất kỳ sự kiện để bắn vì vậy tôi đoán rằng sẽ trở thành một "tính năng" của công cụ của tôi cho bây giờ. Nếu bất kỳ ai có bất kỳ thông tin nào khác cảm thấy tự do để đóng góp.

-1

Nếu bạn sử dụng MacOSX + Parallels Desktop + Windows, Mã của bạn không hoạt động, Do thuộc tính FileSystemWatcher.Path của bạn nhắm mục tiêu đến đường dẫn mac, đó là đường dẫn UNC, nó không được hỗ trợ!

enter image description here