From bdeff0ad81027d114a42d536500ca1f8b9f68872 Mon Sep 17 00:00:00 2001 From: walon Date: Tue, 8 Jun 2021 16:55:51 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90Luban.Client=E3=80=91=E6=94=AF?= =?UTF-8?q?=E6=8C=81watch=E5=A4=9A=E4=B8=AA=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Luban.Client/Source/Program.cs | 59 ++----------- .../Source/Utils/MultiFileWatcher.cs | 84 +++++++++++++++++++ 2 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 src/Luban.Client/Source/Utils/MultiFileWatcher.cs diff --git a/src/Luban.Client/Source/Program.cs b/src/Luban.Client/Source/Program.cs index 9652465..76a4c26 100644 --- a/src/Luban.Client/Source/Program.cs +++ b/src/Luban.Client/Source/Program.cs @@ -1,5 +1,6 @@ using Luban.Client.Common.Net; using Luban.Client.Common.Utils; +using Luban.Client.Utils; using Luban.Common.Protos; using Luban.Common.Utils; using System; @@ -27,12 +28,12 @@ namespace Luban.Client public string CacheMetaInfoFile { get; set; } = ".cache.meta"; - public string WatchDir { get; set; } + public string[] WatchDir { get; set; } } private static NLog.Logger s_logger; - private static FileSystemWatcher s_watcher; + private static MultiFileWatcher s_watcher; private static void PrintUsage(string err) { @@ -99,7 +100,7 @@ Options: case "-w": case "--watch": { - ops.WatchDir = args[++i]; + ops.WatchDir = args[++i].Split(';', ','); break; } case "--": @@ -155,7 +156,7 @@ Options: ThreadPool.SetMaxThreads(64, 10); - if (string.IsNullOrWhiteSpace(options.WatchDir)) + if (options.WatchDir.Length == 0) { int exitCode = GenOnce(options, profile); profile.EndPhaseAndLog(); @@ -164,59 +165,11 @@ Options: else { GenOnce(options, profile); - var watcher = new FileSystemWatcher(options.WatchDir); - watcher.NotifyFilter = NotifyFilters.Attributes - | NotifyFilters.CreationTime - | NotifyFilters.DirectoryName - | NotifyFilters.FileName - | NotifyFilters.LastAccess - | NotifyFilters.LastWrite - | NotifyFilters.Security - | NotifyFilters.Size; - - watcher.Changed += (o, p) => OnWatchChange(options, profile); - watcher.Created += (o, p) => OnWatchChange(options, profile); - watcher.Deleted += (o, p) => OnWatchChange(options, profile); - watcher.Renamed += (o, p) => OnWatchChange(options, profile); - - //watcher.Filter = "*.txt"; - watcher.IncludeSubdirectories = true; - watcher.EnableRaisingEvents = true; - - s_logger.Info("=== start watch. dir:{} ==", options.WatchDir); - s_watcher = watcher; + s_watcher = new MultiFileWatcher(options.WatchDir, () => GenOnce(options, profile)); } } - private static readonly object s_watchLocker = new object(); - private static bool s_watchDirChange = false; - - private static void OnWatchChange(CommandLineOptions options, ProfileTimer profile) - { - lock (s_watchLocker) - { - if (s_watchDirChange) - { - return; - } - s_watchDirChange = true; - - Task.Run(async () => - { - s_logger.Info("=== start new generation =="); - await Task.Delay(200); - - lock (s_watchLocker) - { - s_watchDirChange = false; - GenOnce(options, profile); - } - s_logger.Info("=== watch changes =="); - }); - } - - } private static int GenOnce(CommandLineOptions options, ProfileTimer profile) { diff --git a/src/Luban.Client/Source/Utils/MultiFileWatcher.cs b/src/Luban.Client/Source/Utils/MultiFileWatcher.cs new file mode 100644 index 0000000..8b427dc --- /dev/null +++ b/src/Luban.Client/Source/Utils/MultiFileWatcher.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Client.Utils +{ + class MultiFileWatcher + { + 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(); + private bool _watchDirChange = false; + + public MultiFileWatcher(string[] files, Action onChange) + { + this._onChange = onChange; + + 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); + + s_logger.Info("=== start watch. dir:{} ==", file); + } + } + + private void OnChange(object sender, FileSystemEventArgs e) + { + lock (_watchLocker) + { + if (_watchDirChange) + { + return; + } + _watchDirChange = true; + + Task.Run(async () => + { + await Task.Delay(400); + + lock (_watchLocker) + { + _watchDirChange = false; + try + { + this._onChange(); + } + catch (Exception e) + { + s_logger.Error(e, "OnChange exception"); + } + } + s_logger.Info("=== watch changes =="); + }); + } + } + } +}