using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Luban.Utils { internal class DirectoryWatcher { private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger(); private readonly List _watchers = new List(); private readonly Action _onChange; private readonly object _watchLocker = new object(); public DirectoryWatcher(string[] files, Action onChange) { this._onChange = onChange; s_logger.Info("watching dirs: {0}", string.Join(",", files)); foreach (var file in files) { var watcher = new FileSystemWatcher(file); watcher.NotifyFilter = // NotifyFilters.Attributes //| NotifyFilters.CreationTime NotifyFilters.DirectoryName | NotifyFilters.FileName //| NotifyFilters.LastAccess | NotifyFilters.LastWrite //| NotifyFilters.Security | NotifyFilters.Size; watcher.Changed += this.OnChange; watcher.Created += this.OnChange; watcher.Deleted += this.OnChange; watcher.Renamed += this.OnChange; //watcher.Filter = "*.txt"; watcher.IncludeSubdirectories = true; watcher.EnableRaisingEvents = true; this._watchers.Add(watcher); } } private static readonly List _filterSuffixs = new List { ".xlsx", ".csv", ".xls", ".xlsm", ".json", ".lua", ".xml", ".yml", }; private void OnChange(object sender, FileSystemEventArgs e) { var dirtyName = e.Name; if (string.IsNullOrWhiteSpace(dirtyName) || !_filterSuffixs.Any(dirtyName.EndsWith) || dirtyName.Contains('~') || dirtyName.Contains('$')) { return; } lock (_watchLocker) { s_logger.Trace("== mark dirty:{}", e.FullPath); try { this._onChange(); } catch (Exception e2) { s_logger.Error(e2, "OnChange exception"); } } } } }