FileSystemWatcher Network Disconnect - PullRequest
       2

FileSystemWatcher Network Disconnect

9 голосов
/ 06 февраля 2012

У меня есть FileSystemWatcher, отслеживающий файл на сетевом ресурсе.Если происходит событие, делающее общий ресурс недоступным, возможно, из-за неполадок в сети, FileSystemWatcher отключается.

Очевидно, что я могу обработать событие «Ошибка», возможно, я сделаю несколько журналов и многие статьи предлагают повторно подключить FSWвнутри обработчика событий ошибки.

Но что, если сетевой ресурс все еще недоступен в событии ошибки.Затем мне нужно ввести таймер, чтобы проверить, доступен ли общий сетевой ресурс, и попытаться повторно подключить FSW.

1) Есть ли лучший подход?

2) Есть ли свойство, которое позволяетмне определить, что FSW отключился от файла?Я заметил, что есть негласный член FSW «stopListening», который, по-видимому, устанавливается в значение true, когда FSW отключается.Но это не публично разоблачено

Любая помощь будет оценена ...

Спасибо, Кевин

Ответы [ 3 ]

7 голосов
/ 23 февраля 2012

Пара комментариев и предложений ... (которые росли и росли, когда я печатал ... извините)

Событие FileSystemWatcher.Error вызывается, когда FileSystemWatcher получает так много событий, происходящих так быстро, чтоэто не может справиться со всеми ними.Он не срабатывает, когда возникает ошибка при просмотре файловой системы (например, отключение сети).

Я считаю, что у меня была похожая ситуация.Проблема заключается в том, что когда сетевое соединение прерывается, FileSystemWatcher никогда не будет запускать событие, потому что он на самом деле не может видеть то, что он должен наблюдать, но он, кажется, не знает об этом.Когда сетевое соединение возвращается, FileSystemWatcher не восстанавливается, то есть он все еще не может видеть (восстановленное) соединение.Единственное решение, которое мы нашли, которое, казалось, работало надежно, состояло в том, чтобы иметь таймер, который регулярно удалял весь объект FileSystemWatcher и создавал новый, устанавливая все события и папку просмотра и т. Д. Так как удаление и создание нового FileSystemWatcher - это (относительно быстро (т. е. в миллисекундах) вы можете настроить таймер на активацию каждые 10 секунд или около того, не израсходовав слишком много процессора.Конечно, если сеть все еще отсутствует, FileSystemWatcher не сможет видеть сеть независимо от того, что вы делаете.Но ничего страшного, он попытается через 10 секунд.

В этом решении следует обратить внимание на две вещи:

  1. Когда таймер активируется, он должен проверить, что FileSystemWatcherв настоящее время не обрабатывает какие-либо события, и он должен ждать, если это так.Поэтому в событии таймера остановите Timer, остановите FileSystemWatcher от инициирования событий, затем дождитесь завершения любых событий FileSystemWatcher (использование lock (...) {...} - хороший способ сделать это).
  2. После удаления и повторного создания FileSystemWatcher вам необходимо вручную проверить любые события, которые могли произойти во время обновления FileSystemWatcher (или когда сеть была отключена).Например, если вы наблюдаете за созданием файлов, и файл создается при обновлении FileSystemWatcher или при отсутствии сетевого подключения, вы не получите события для этих файлов при запуске нового экземпляра FileSystemWatcher (поскольку файлы уже созданы).

Надеюсь, это поможет.

1 голос
/ 12 марта 2012

Продолжение в этом.По предложению ресурса Microsoft на форумах MSDN я добавил это в Microsoft Connect.

Ключевые моменты из отзывов от Microsoft: - Событие ошибки не только для переполнения внутреннего буфера - Они добавят возможностьвыставив свойство stopListening в список предложений клиентов

Ссылка здесь: http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

0 голосов
/ 12 декабря 2014

Не будет ли что-то подобное этой работой? Кажется, работает для моего простого теста.

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
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...