diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index 36cecd3b..0d64b3b4 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -75,6 +75,7 @@ namespace Netch.Forms SelectLastServer(); ServerHelper.DelayTestHelper.UpdateInterval(); + ModeHelper.InitWatcher(); ModeHelper.Load(); LoadModes(); SelectLastMode(); @@ -677,6 +678,12 @@ namespace Netch.Forms public void LoadModes() { + if (InvokeRequired) + { + Invoke(new Action(LoadModes)); + return; + } + ModeComboBox.Items.Clear(); ModeComboBox.Items.AddRange(Global.Modes.Cast().ToArray()); ModeComboBox.Tag = null; diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index 93a4306a..7c659bc6 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -51,6 +51,7 @@ + diff --git a/Netch/Utils/ModeHelper.cs b/Netch/Utils/ModeHelper.cs index e3a2747a..98a471a2 100644 --- a/Netch/Utils/ModeHelper.cs +++ b/Netch/Utils/ModeHelper.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Reactive.Linq; using Netch.Controllers; using Netch.Enums; using Netch.Interfaces; @@ -15,33 +16,49 @@ namespace Netch.Utils { public const string DisableModeDirectoryFileName = "disabled"; + private static FileSystemWatcher _fileSystemWatcher = null!; + public static string ModeDirectoryFullName => Path.Combine(Global.NetchDir, "mode"); - private static readonly FileSystemWatcher FileSystemWatcher; - - public static bool SuspendWatcher { get; set; } = false; - - static ModeHelper() + public static bool SuspendWatcher { - FileSystemWatcher = new FileSystemWatcher(ModeDirectoryFullName) + get => _fileSystemWatcher.EnableRaisingEvents; + set => _fileSystemWatcher.EnableRaisingEvents = value; + } + + public static void InitWatcher() + { + _fileSystemWatcher = new FileSystemWatcher(ModeDirectoryFullName) { - NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName, + NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName, IncludeSubdirectories = true, EnableRaisingEvents = true }; - FileSystemWatcher.Changed += OnModeChanged; - FileSystemWatcher.Created += OnModeChanged; - FileSystemWatcher.Deleted += OnModeChanged; - FileSystemWatcher.Renamed += OnModeChanged; + var created = Observable.FromEventPattern(h => _fileSystemWatcher.Created += h, + h => _fileSystemWatcher.Created -= h) + .Select(x => x.EventArgs); + + var changed = Observable.FromEventPattern(h => _fileSystemWatcher.Changed += h, + h => _fileSystemWatcher.Changed -= h) + .Select(x => x.EventArgs); + + var deleted = Observable.FromEventPattern(h => _fileSystemWatcher.Deleted += h, + h => _fileSystemWatcher.Deleted -= h) + .Select(x => x.EventArgs); + + var renamed = Observable.FromEventPattern(h => _fileSystemWatcher.Renamed += h, + h => _fileSystemWatcher.Renamed -= h) + .Select(x => x.EventArgs); + + var o = Observable.Merge(created, deleted, renamed, changed); + o.Throttle(TimeSpan.FromSeconds(3)).Select(_ => true).Subscribe(OnNext, exception => Log.Error(exception, "FileSystemWatcherError")); } - private static void OnModeChanged(object sender, FileSystemEventArgs e) + private static void OnNext(bool obj) { - if (SuspendWatcher) - return; - Load(); + Global.MainForm.LoadModes(); } public static string GetRelativePath(string fullName) @@ -58,23 +75,19 @@ namespace Netch.Utils return Path.Combine(ModeDirectoryFullName, relativeName); } - /// - /// 从模式文件夹读取模式 - /// public static void Load() { Global.Modes.Clear(); - LoadModeDirectory(ModeDirectoryFullName); - + LoadCore(ModeDirectoryFullName); Sort(); } - private static void LoadModeDirectory(string modeDirectory) + private static void LoadCore(string modeDirectory) { try { foreach (var directory in Directory.GetDirectories(modeDirectory)) - LoadModeDirectory(directory); + LoadCore(directory); // skip Directory with a disabled file in if (File.Exists(Path.Combine(modeDirectory, DisableModeDirectoryFileName)))