2012-02-06 29 views
9

Tôi có một FileSystemWatcher giám sát một tập tin trên một mạng chia sẻ. Nếu một sự kiện xảy ra để làm cho chia sẻ không có sẵn, có thể do sự cố mạng, FileSystemWatcher sẽ bị ngắt kết nối.FileSystemWatcher Network Disconnect

Rõ ràng là tôi có thể xử lý sự kiện "Lỗi", có thể thực hiện một số thao tác ghi nhật ký và rất nhiều bài viết đề xuất kết nối lại FSW bên trong trình xử lý sự kiện lỗi.

Nhưng điều gì xảy ra nếu chia sẻ mạng vẫn không khả dụng trong sự kiện lỗi. Sau đó tôi cần phải giới thiệu một bộ đếm thời gian để kiểm tra xem chia sẻ mạng có sẵn không và cố gắng kết nối lại FSW.

1) Có cách tiếp cận tốt hơn không?

2) Có tài sản nào cho phép tôi xác định rằng FSW đã bị ngắt kết nối khỏi tệp không? Tôi nhận thấy có một thành viên không công khai của FSW "stopListening", có vẻ như được đặt thành true khi FSW bị ngắt kết nối. Nhưng điều này là không công khai tiếp xúc

Bất kỳ trợ giúp sẽ được đánh giá cao ...

Cảm ơn Kevin

+0

thể trùng lặp của [FileSystemWatcher và ngắt kết nối mạng?] (Http://stackoverflow.com/questions/281573/filesystemwatcher-and-network-disconnect) –

+0

Cảm ơn đã phản ứng Erno, nhưng không có nó không phải. Tôi biết rằng tôi có thể sử dụng sự kiện Lỗi để kết nối lại. Nhưng khi sự kiện Lỗi được nêu lên điều gì sẽ xảy ra nếu chia sẻ mạng không khả dụng? Trừ khi tôi có một số loại hẹn giờ/hẹn giờ cố gắng kết nối lại, tôi không có sự kiện nào khác để cố gắng kết nối lại! Ngoài ra, FSW không tiếp xúc với một tài sản công cộng để cho tôi biết nó bị ngắt kết nối –

+0

Theo bài viết tôi đề nghị có một sự kiện lỗi mà bạn có thể sử dụng. Và bộ hẹn giờ là một ý tưởng hay để thăm dò tính khả dụng. –

Trả lời

1

Theo dõi trong phần này. Theo gợi ý của một tài nguyên Microsoft trên diễn đàn MSDN, tôi đã thêm điều này vào Microsoft Connect.

Những điểm mấu chốt từ những phản hồi từ Microsoft: - sự kiện Lỗi không chỉ dành cho nội bộ đệm tràn - Họ sẽ bổ sung thêm khả năng để lộ stopListening tài sản vào danh sách của họ về lời đề nghị của khách hàng

liên kết ở đây: http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

+0

Trang không còn có sẵn hoặc không có quyền xem nó - làm cho câu trả lời vô giá trị :( – Darren

7

Một vài ý kiến ​​và đề xuất ... (mà phát triển và tăng trưởng như tôi đã gõ ... xin lỗi)

Sự kiện FileSystemWatcher.Error được kích hoạt khi FileSystemWatcher nhận được quá nhiều sự kiện diễn ra quá nhanh đến mức không thể xử lý tất cả. Nó không bị đuổi khi xảy ra lỗi khi xem hệ thống tệp (chẳng hạn mạng bị loại bỏ).

Tôi tin rằng tôi đã có một tình huống tương tự. Vấn đề là khi kết nối mạng bị ngắt, FileSystemWatcher sẽ không bao giờ có một sự kiện được kích hoạt, bởi vì nó thực sự không thể nhìn thấy những gì nó được cho là đang xem, nhưng nó dường như không nhận thức được thực tế. Khi kết nối mạng trở lại, FileSystemWatcher không phục hồi - tức là nó vẫn không thể nhìn thấy kết nối (đã khôi phục). Giải pháp duy nhất mà chúng tôi đưa ra có vẻ như hoạt động đáng tin cậy là có bộ đếm thời gian thường xuyên xóa toàn bộ đối tượng FileSystemWatcher và tạo một bộ hẹn giờ mới, thiết lập tất cả các sự kiện và thư mục xem v.v. Kể từ khi thả và tạo một FileSystemWatcher mới là (tương đối) nhanh (tức là mili giây), bạn có thể đặt bộ hẹn giờ để kích hoạt sau mỗi 10 giây hoặc lâu hơn mà không cần sử dụng quá nhiều bộ xử lý. Tất nhiên, nếu mạng vẫn còn tồn tại, FileSystemWatcher sẽ không thể xem mạng bất kể bạn làm gì. Nhưng đó là OK, nó sẽ thử lại trong 10 giây nữa.

Hai điều cần xem ra cho với giải pháp này:

  1. Khi bộ đếm thời gian kích hoạt, nó cần phải xem xét rằng việc FileSystemWatcher hiện không xử lý bất kỳ sự kiện, và nó cần phải chờ đợi nếu nó được. Vì vậy, trong sự kiện bộ đếm thời gian, dừng Bộ hẹn giờ, dừng FileSystemWatcher từ việc nâng cao sự kiện, sau đó đợi mọi sự kiện FileSystemWatcher kết thúc (sử dụng khóa (...) {...} là cách tốt để thực hiện việc này).
  2. Sau khi thả và tạo lại FileSystemWatcher, bạn cần kiểm tra thủ công bất kỳ sự kiện nào có thể xảy ra trong khi FileSystemWatcher đang được làm mới (hoặc trong khi mạng bị gián đoạn). Ví dụ: nếu bạn đang xem tệp đang được tạo và tệp được tạo trong khi làm mới FileSystemWatcher hoặc khi kết nối mạng bị tắt, bạn sẽ không nhận được sự kiện cho các tệp đó khi bạn khởi động phiên bản mới của FileSystemWatcher (vì các tệp đã được tạo).

Tôi hy vọng điều đó sẽ hữu ích.

+0

Cảm ơn câu trả lời Mark. Sau khi đọc lại tài liệu MSDN, tôi thấy rằng bạn là chính xác, sự kiện lỗi không thực sự bị sa thải khi xảy ra lỗi khi xem hệ thống tệp, đó là một sự hiểu biết sai về phía tôi. –

+1

Cách tiếp cận của bạn là thú vị, tuy nhiên (có thể do một lỗi thiết kế), FileSystemWatcher thực sự là một tĩnh bên trong một dịch vụ WCF khối lượng cao. Vì vậy, khái niệm phải khởi tạo lại nó sau mỗi 10 giây có lẽ không phải là một lựa chọn cho chúng tôi, thậm chí một cú đánh hiệu suất nhỏ có thể tốn kém cho thời gian phản hồi yêu cầu của chúng tôi. Có vẻ như không có câu trả lời, vì chúng tôi hoàn toàn không thể dựa vào sự kiện lỗi, giải pháp tối ưu sẽ là yếu tố quyết định giải pháp của chúng tôi để xóa FileSystemWatcher vì nó dường như là một cách tiếp cận không đáng tin cậy. –

0

Chẳng phải công việc này sẽ như thế nào? Dường như làm việc cho trường hợp thử nghiệm đơn giản của tôi.

var fsw = new FileSystemWatcher("[folder]", "*.*") { IncludeSubdirectories = true}; 
var fsw_processing = false; 
fsw.Deleted += (s, e) => 
{ 
    fsw_processing = true; 
    fsw.EnableRaisingEvents = false; 
    //...... 
    fsw.EnableRaisingEvents = true; 
    fsw_processing = false; 
};  
fsw.Changed += (s, e) => 
{ 
    fsw_processing = true; 
    fsw.EnableRaisingEvents = false; 
    //...... 
    fsw.EnableRaisingEvents = true; 
    fsw_processing = false; 
};  
//governor thread to check FileSystemWatcher is still connected. 
//It seems to disconnects on network outages etc. 
Task.Run(() => 
{ 
    while (true) 
    { 
     if (fsw.EnableRaisingEvents == false && fsw_processing == false) 
     {       
      try 
      {fsw.EnableRaisingEvents = true;} 
      catch (Exception) { fsw.EnableRaisingEvents = false; }    
     } 
     System.Threading.Thread.Sleep(1000 * 10);//sleep 10 secs 
    } 
}); 
Các vấn đề liên quan