SystemFileWatcher не запускает события - PullRequest
0 голосов
/ 20 марта 2019

Я пытался понять, почему мой FSW не запускает какие-либо события.Я создаю экземпляр нового объекта моего ниже класса в моем Application_Start и делаю WatchFile (), но ничего не происходит = (

public class FileWatcherClass
    {
        private FileSystemWatcher _watcher;
        public void WatchFile(string fileName, string directory)
        {
            // Create a new FileSystemWatcher and set its properties.
            using (_watcher = new FileSystemWatcher(directory, "*.xml"))
            {
                _watcher.NotifyFilter = NotifyFilters.Attributes |
                                        NotifyFilters.CreationTime |
                                        NotifyFilters.FileName |
                                        NotifyFilters.LastAccess |
                                        NotifyFilters.LastWrite |
                                        NotifyFilters.Size |
                                        NotifyFilters.Security;

                // Add event handlers.
                _watcher.Changed +=
                new FileSystemEventHandler(OnChanged);

                // Begin watching.
                _watcher.EnableRaisingEvents = true;

            }
        }

        // Define the event handlers.
        public void OnChanged(object source, FileSystemEventArgs e) { 
            do something..
        }
    }

Ответы [ 2 ]

5 голосов
/ 20 марта 2019

Проблема связана с использованием оператора using:

using (_watcher = new FileSystemWatcher(directory, "*.xml"))

Когда выполнение достигает конца блока using, наблюдатель удаляется, что означает, что он больше не может вызывать события,

Удалите использование, чтобы решить вашу проблему:

_watcher = new FileSystemWatcher(directory, "*.xml");

Но возникает другая проблема - никогда не выбрасывать наблюдателя.Подход может заключаться в реализации IDisposable на FileWatcherClass и последующей утилизации наблюдателя по мере необходимости:

public void Dispose()
{
    _watcher?.Dispose(); // if _watcher isn't null, dispose it
}

Тогда вы можете просто утилизировать свой экземпляр FileWatcherClass, когда закончите с ним.

0 голосов
/ 21 марта 2019

Вот немного более гибкая реализация.

Использование :

    static void Main(string[] args)
    {
        using (var watcherManager= new FileSystemWatcherManager())
        {
            watcherManager.OnChangedDetected += (a) =>
            {
                // General event
            };

            watcherManager.RegisterWatcher(@"C:\temp\helloworld");
            watcherManager.RegisterWatcher(@"C:\temp\api-demo", customChangeEvent: (s, e) =>
            {
                // Handle change directly
            });

            Console.ReadKey();
        };
   }

Реализация :

public sealed class FileSystemWatcherManager : IDisposable
{
    private bool _disposed = false;
    private readonly Dictionary<string, FileSystemWatcher> _watchers;
    public delegate void ChangedDetected(FileSystemEventArgs args);
    public event ChangedDetected OnChangedDetected;

    public FileSystemWatcherManager()
    {
        _watchers = new Dictionary<string, FileSystemWatcher>();
    }

    ~FileSystemWatcherManager()
    {
        Dispose(false);
    }

    public FileSystemWatcher RegisterWatcher(string directoryPath, string filter = "*", FileSystemEventHandler customChangeEvent = null)
    {
        if (Directory.Exists(directoryPath))
        {
            if (!_watchers.ContainsKey(directoryPath))
            {
                var watcher = new FileSystemWatcher(directoryPath, filter)
                {
                    EnableRaisingEvents = true,
                    IncludeSubdirectories = true
                };
                watcher.NotifyFilter =  NotifyFilters.Attributes |
                                        NotifyFilters.CreationTime |
                                        NotifyFilters.FileName |
                                        NotifyFilters.LastAccess |
                                        NotifyFilters.LastWrite |
                                        NotifyFilters.Size |
                                        NotifyFilters.Security;

                if (customChangeEvent != null)
                    watcher.Changed += customChangeEvent;
                else
                    watcher.Changed += Watcher_Changed;

                _watchers.Add(directoryPath, watcher);
            }
        }
        else
        {
            throw new InvalidOperationException($"Invalid Directory: {directoryPath}");
        }

        return _watchers.TryGetValue(directoryPath, out FileSystemWatcher value) ? value : null;
    }

    private void Watcher_Changed(object sender, FileSystemEventArgs e)
    {
        OnChangedDetected?.Invoke(e);
    }

    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (_disposed)
        {
            if (disposing)
            {
                foreach(KeyValuePair<string,FileSystemWatcher> pair in _watchers)
                {
                    pair.Value.Dispose();                       
                }

                _watchers.Clear();
            }

            _disposed = true;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...