diff --git a/FileManager/AudibleFileStorage.cs b/FileManager/AudibleFileStorage.cs index b2ee12a5..fdbf1a77 100644 --- a/FileManager/AudibleFileStorage.cs +++ b/FileManager/AudibleFileStorage.cs @@ -34,7 +34,7 @@ namespace FileManager } } - private static BackgroundFileSystem BookDirectoryFiles { get; } = new BackgroundFileSystem(); + private static BackgroundFileSystem BookDirectoryFiles { get; set; } #endregion #region instance @@ -47,6 +47,7 @@ namespace FileManager { extensions_noDots = Extensions.Select(ext => ext.Trim('.')).ToList(); extAggr = extensions_noDots.Aggregate((a, b) => $"{a}|{b}"); + BookDirectoryFiles ??= new BackgroundFileSystem(BookDirectoryFiles, "*.*", SearchOption.AllDirectories); } public void Refresh() @@ -76,7 +77,15 @@ namespace FileManager { //If user changed the BooksDirectory, reinitialize. if (storageDir != BookDirectoryFiles.RootDirectory) - BookDirectoryFiles.Init(storageDir, "*.*", SearchOption.AllDirectories); + { + lock (BookDirectoryFiles) + { + if (storageDir != BookDirectoryFiles.RootDirectory) + { + BookDirectoryFiles = new BackgroundFileSystem(storageDir, "*.*", SearchOption.AllDirectories); + } + } + } firstOrNull = BookDirectoryFiles.FindFile(regexPattern, RegexOptions.IgnoreCase); } diff --git a/FileManager/BackgroundFileSystem.cs b/FileManager/BackgroundFileSystem.cs index a239581c..1ed670ac 100644 --- a/FileManager/BackgroundFileSystem.cs +++ b/FileManager/BackgroundFileSystem.cs @@ -18,12 +18,19 @@ namespace FileManager private FileSystemWatcher fileSystemWatcher { get; set; } private BlockingCollection directoryChangesEvents { get; set; } private Task backgroundScanner { get; set; } - private List fsCache { get; set; } + private List fsCache { get; } = new(); + + public BackgroundFileSystem(string rootDirectory, string searchPattern, SearchOption searchOptions) + { + RootDirectory = rootDirectory; + SearchPattern = searchPattern; + SearchOption = searchOptions; + + Init(); + } public string FindFile(string regexPattern, RegexOptions options) { - if (fsCache is null) return null; - lock (fsCache) { return fsCache.FirstOrDefault(s => Regex.IsMatch(s, regexPattern, options)); @@ -32,8 +39,6 @@ namespace FileManager public void RefreshFiles() { - if (fsCache is null) return; - lock (fsCache) { fsCache.Clear(); @@ -41,19 +46,12 @@ namespace FileManager } } - public void Init(string rootDirectory, string searchPattern, SearchOption searchOptions) + private void Init() { - RootDirectory = rootDirectory; - SearchPattern = searchPattern; - SearchOption = searchOptions; + Stop(); - //Calling CompleteAdding() will cause background scanner to terminate. - directoryChangesEvents?.CompleteAdding(); - fsCache?.Clear(); - directoryChangesEvents?.Dispose(); - fileSystemWatcher?.Dispose(); - - fsCache = Directory.EnumerateFiles(RootDirectory, SearchPattern, SearchOption).ToList(); + lock (fsCache) + fsCache.AddRange(Directory.EnumerateFiles(RootDirectory, SearchPattern, SearchOption)); directoryChangesEvents = new BlockingCollection(); fileSystemWatcher = new FileSystemWatcher(RootDirectory); @@ -64,28 +62,31 @@ namespace FileManager fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.EnableRaisingEvents = true; - //Wait for background scanner to terminate before reinitializing. - backgroundScanner?.Wait(); backgroundScanner = new Task(BackgroundScanner); backgroundScanner.Start(); } + private void Stop() + { + //Stop raising events + fileSystemWatcher?.Dispose(); - private void AddUniqueFiles(IEnumerable newFiles) - { - foreach (var file in newFiles) - { - AddUniqueFile(file); - } - } - private void AddUniqueFile(string newFile) - { - if (!fsCache.Contains(newFile)) - fsCache.Add(newFile); + //Calling CompleteAdding() will cause background scanner to terminate. + directoryChangesEvents?.CompleteAdding(); + + //Wait for background scanner to terminate before reinitializing. + backgroundScanner?.Wait(); + + //Dispose of directoryChangesEvents after backgroundScanner exists. + directoryChangesEvents?.Dispose(); + + lock (fsCache) + fsCache.Clear(); } private void FileSystemWatcher_Error(object sender, ErrorEventArgs e) { - Init(RootDirectory, SearchPattern, SearchOption); + Stop(); + Init(); } private void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e) @@ -97,28 +98,26 @@ namespace FileManager private void BackgroundScanner() { while (directoryChangesEvents.TryTake(out FileSystemEventArgs change, -1)) - UpdateLocalCache(change); + { + lock (fsCache) + UpdateLocalCache(change); + } } - private void UpdateLocalCache(FileSystemEventArgs change) + private void UpdateLocalCache(FileSystemEventArgs change) { - lock (fsCache) + if (change.ChangeType == WatcherChangeTypes.Deleted) { - if (change.ChangeType == WatcherChangeTypes.Deleted) - { - RemovePath(change.FullPath); - } - else if (change.ChangeType == WatcherChangeTypes.Created) - { - AddPath(change.FullPath); - } - else if (change.ChangeType == WatcherChangeTypes.Renamed) - { - var renameChange = change as RenamedEventArgs; - - RemovePath(renameChange.OldFullPath); - AddPath(renameChange.FullPath); - } + RemovePath(change.FullPath); + } + else if (change.ChangeType == WatcherChangeTypes.Created) + { + AddPath(change.FullPath); + } + else if (change.ChangeType == WatcherChangeTypes.Renamed && change is RenamedEventArgs renameChange) + { + RemovePath(renameChange.OldFullPath); + AddPath(renameChange.FullPath); } } @@ -137,6 +136,21 @@ namespace FileManager else AddUniqueFile(path); } + private void AddUniqueFiles(IEnumerable newFiles) + { + foreach (var file in newFiles) + { + AddUniqueFile(file); + } + } + private void AddUniqueFile(string newFile) + { + if (!fsCache.Contains(newFile)) + fsCache.Add(newFile); + } + #endregion + + ~BackgroundFileSystem() => Stop(); } } diff --git a/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs b/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs index 1f4cf04d..e736b938 100644 --- a/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs +++ b/LibationWinForms/EditTagsDataGridViewImageButtonColumn.cs @@ -23,8 +23,6 @@ namespace LibationWinForms if (DataGridView.Rows[RowIndex].DefaultCellStyle.ForeColor != foreColor) { DataGridView.Rows[RowIndex].DefaultCellStyle.ForeColor = foreColor; - - DataGridView.InvalidateRow(RowIndex); } if (tagsString.Length == 0)