diff --git a/SDMetaTool/Cache/IPngFileDataSource.cs b/SDMetaTool/Cache/IPngFileDataSource.cs index 6284a81..ed850cc 100644 --- a/SDMetaTool/Cache/IPngFileDataSource.cs +++ b/SDMetaTool/Cache/IPngFileDataSource.cs @@ -1,14 +1,15 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace SDMetaTool.Cache { - public interface IPngFileDataSource : IDisposable + public interface IPngFileDataSource : IAsyncDisposable { - IEnumerable GetAll(); - PngFile ReadPngFile(string realFileName); - void WritePngFile(PngFile info); - void BeginTransaction(); - void CommitTransaction(); + Task> GetAll(); + Task ReadPngFile(string realFileName); + Task WritePngFile(PngFile info); + Task BeginTransaction(); + Task CommitTransaction(); } } \ No newline at end of file diff --git a/SDMetaTool/Cache/JsonDataSource.cs b/SDMetaTool/Cache/JsonDataSource.cs index 73f0035..232c866 100644 --- a/SDMetaTool/Cache/JsonDataSource.cs +++ b/SDMetaTool/Cache/JsonDataSource.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; +using System.Runtime.CompilerServices; using System.Text.Json; +using System.Threading.Tasks; namespace SDMetaTool.Cache { @@ -21,7 +23,7 @@ public JsonDataSource(IFileSystem fileSystem) cache = this.InitialGetAll().ToDictionary(p => p.FileName, p => p); } - public IEnumerable GetAll() + public async Task> GetAll() { return cache.Values; } @@ -43,7 +45,7 @@ private IEnumerable InitialGetAll() } } - private void WriteCache(IEnumerable cache) + private async Task WriteCache(IEnumerable cache) { var path = cachePath.GetPath(); @@ -62,13 +64,13 @@ private void WriteCache(IEnumerable cache) fileSystem.File.WriteAllText(path, serialized); } - public PngFile ReadPngFile(string realFileName) + public async Task ReadPngFile(string realFileName) { cache.TryGetValue(realFileName, out PngFile value); return value; } - public void WritePngFile(PngFile info) + public async Task WritePngFile(PngFile info) { if (info != null) { @@ -76,14 +78,9 @@ public void WritePngFile(PngFile info) } } - public void Dispose() + public async ValueTask DisposeAsync() { - Flush(); - } - - public void Flush() - { - this.WriteCache(cache.Values); + await this.WriteCache(cache.Values); } private static PngFile PngFileDTOToPngFile(PngFileDTO trackDTO) @@ -110,11 +107,11 @@ private static PngFileDTO PngFileToPngFileDTO(PngFile track) }; } - public void BeginTransaction() + public async Task BeginTransaction() { } - public void CommitTransaction() + public async Task CommitTransaction() { } diff --git a/SDMetaTool/Cache/SqliteDataSource.cs b/SDMetaTool/Cache/SqliteDataSource.cs index 45412fc..24f58d3 100644 --- a/SDMetaTool/Cache/SqliteDataSource.cs +++ b/SDMetaTool/Cache/SqliteDataSource.cs @@ -3,8 +3,10 @@ using NLog; using System; using System.Collections.Generic; +using System.Data.Common; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace SDMetaTool.Cache { @@ -12,7 +14,7 @@ public class SqliteDataSource : IPngFileDataSource { const string TableName = "PngFiles"; private readonly SqliteConnection connection; - private SqliteTransaction transaction; + private DbTransaction transaction; private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private readonly string[] columns = new string[] @@ -224,15 +226,15 @@ internal GenerationParams ToGenerationParams() } } - public void Dispose() + public async ValueTask DisposeAsync() { - this.CommitTransaction(); - connection.Dispose(); + await this.CommitTransaction(); + await connection.DisposeAsync(); } - public IEnumerable GetAll() + public async Task> GetAll() { - var reader = connection.Query( + var reader = await connection.QueryAsync( $@"SELECT * FROM {TableName}" ); @@ -240,9 +242,9 @@ public IEnumerable GetAll() return reader.Select(p => p.ToModel()); } - public PngFile ReadPngFile(string realFileName) + public async Task ReadPngFile(string realFileName) { - var reader = connection.QueryFirstOrDefault( + var reader = await connection.QueryFirstOrDefaultAsync( $@"SELECT * FROM {TableName} WHERE FileName = @FileName @@ -258,29 +260,26 @@ public PngFile ReadPngFile(string realFileName) } } - public void WritePngFile(PngFile info) + public async Task WritePngFile(PngFile info) { - connection.Execute( + await connection.ExecuteAsync( insertSql, DataRow.FromModel(info), this.transaction ); } - public void BeginTransaction() + public async Task BeginTransaction() { - if (this.transaction == null) - { - this.transaction = this.connection.BeginTransaction(); - } + this.transaction ??= await this.connection.BeginTransactionAsync(); } - public void CommitTransaction() + public async Task CommitTransaction() { if (this.transaction != null) { - this.transaction.Commit(); - this.transaction.Dispose(); + await this.transaction.CommitAsync(); + await this.transaction.DisposeAsync(); this.transaction = null; } } diff --git a/SDMetaTool/CachedPngFileLoader.cs b/SDMetaTool/CachedPngFileLoader.cs index a33777e..df7c39a 100644 --- a/SDMetaTool/CachedPngFileLoader.cs +++ b/SDMetaTool/CachedPngFileLoader.cs @@ -1,5 +1,6 @@ using SDMetaTool.Cache; using System.IO.Abstractions; +using System.Threading.Tasks; namespace SDMetaTool { @@ -19,19 +20,19 @@ public CachedPngFileLoader( this.fileSystem = fileSystem; } - public PngFile GetPngFile(string filename) + public async Task GetPngFile(string filename) { var fileInfo = fileSystem.FileInfo.New(filename); - var pngFile = pngFileDataSource.ReadPngFile(filename); + var pngFile = await pngFileDataSource.ReadPngFile(filename); if (pngFile != null && pngFile.LastUpdated == fileInfo.LastWriteTime) { return pngFile; } else { - pngFile = inner.GetPngFile(filename); + pngFile = await inner.GetPngFile(filename); pngFile.Exists = true; - pngFileDataSource.WritePngFile(pngFile); + await pngFileDataSource.WritePngFile(pngFile); return pngFile; } } diff --git a/SDMetaTool/IPngFileListProcessor.cs b/SDMetaTool/IPngFileListProcessor.cs index 75f680d..c0bdc2e 100644 --- a/SDMetaTool/IPngFileListProcessor.cs +++ b/SDMetaTool/IPngFileListProcessor.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using System.Threading.Tasks; namespace SDMetaTool { public interface IPngFileListProcessor { - void ProcessPngFiles(string root); + Task ProcessPngFiles(string root); } } diff --git a/SDMetaTool/IPngFileLoader.cs b/SDMetaTool/IPngFileLoader.cs index 3df6eff..d154025 100644 --- a/SDMetaTool/IPngFileLoader.cs +++ b/SDMetaTool/IPngFileLoader.cs @@ -1,7 +1,9 @@ -namespace SDMetaTool +using System.Threading.Tasks; + +namespace SDMetaTool { public interface IPngFileLoader { - PngFile GetPngFile(string filename); + Task GetPngFile(string filename); } } \ No newline at end of file diff --git a/SDMetaTool/PngFileLoader.cs b/SDMetaTool/PngFileLoader.cs index a37ce08..a32c3d6 100644 --- a/SDMetaTool/PngFileLoader.cs +++ b/SDMetaTool/PngFileLoader.cs @@ -5,6 +5,7 @@ using System; using System.IO.Abstractions; using System.Linq; +using System.Threading.Tasks; namespace SDMetaTool { @@ -20,13 +21,13 @@ public PngFileLoader(IFileSystem fileSystem) } - public PngFile GetPngFile(string filename) + public async Task GetPngFile(string filename) { logger.Info($"Indexing: {filename}"); try { - return ReadPngFile(fileSystem, filename); + return await ReadPngFile(fileSystem, filename); } catch (Exception ex) { @@ -35,7 +36,7 @@ public PngFile GetPngFile(string filename) } } - public PngFile ReadPngFile(IFileSystem fileSystem, string filename) + private async Task ReadPngFile(IFileSystem fileSystem, string filename) { var fileInfo = fileSystem.FileInfo.New(filename); diff --git a/SDMetaTool/Processors/CSVPngFileLister.cs b/SDMetaTool/Processors/CSVPngFileLister.cs index 0239972..0a94bde 100644 --- a/SDMetaTool/Processors/CSVPngFileLister.cs +++ b/SDMetaTool/Processors/CSVPngFileLister.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Threading.Tasks; namespace SDMetaTool.Processors { @@ -22,13 +23,16 @@ public CSVPngFileLister(IFileLister fileLister, IPngFileLoader pngFileLoader, st this.distinct = distinct; } - public void ProcessPngFiles(string root) + public async Task ProcessPngFiles(string root) { using var writer = new StreamWriter(outfile); using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture); var fileNames = fileLister.GetList(root); - var pngFiles = fileNames.Select(p => pngFileLoader.GetPngFile(p)).Where(p => p != null).OrderBy(p => p.FileName).ToList(); + var tasks = fileNames.Select(p => pngFileLoader.GetPngFile(p)).ToList(); + await Task.WhenAll(tasks.ToArray()); + + var pngFiles = tasks.Select(p => p.Result).Where(p => p != null).OrderBy(p => p.FileName).ToList(); var csvs = distinct ? GetCSVDistinct(pngFiles) : GetCSVPerItem(pngFiles); csv.WriteRecords(csvs); diff --git a/SDMetaTool/Processors/Rescan.cs b/SDMetaTool/Processors/Rescan.cs index a9d4c38..0152a55 100644 --- a/SDMetaTool/Processors/Rescan.cs +++ b/SDMetaTool/Processors/Rescan.cs @@ -1,6 +1,7 @@ using NLog; using SDMetaTool.Cache; using System.Linq; +using System.Threading.Tasks; namespace SDMetaTool.Processors { @@ -21,13 +22,13 @@ public Rescan( this.pngFileLoader = pngFileLoader; } - public void ProcessPngFiles(string root) + public async Task ProcessPngFiles(string root) { logger.Info("Rescan started"); - pngFileDataSource.BeginTransaction(); + await pngFileDataSource.BeginTransaction(); var fileNames = fileLister.GetList(root); - var knownFiles = pngFileDataSource.GetAll(); + var knownFiles = await pngFileDataSource.GetAll(); var deleted = knownFiles.Where(p => p.Exists).Select(p => p.FileName).Except(fileNames); @@ -36,18 +37,22 @@ public void ProcessPngFiles(string root) { var fileToDelete = knownFilesLookup[file].Single(); fileToDelete.Exists = false; - pngFileDataSource.WritePngFile(fileToDelete); + await pngFileDataSource.WritePngFile(fileToDelete); logger.Info("Removing " + file); } - var newFiles = fileNames.Except(knownFiles.Where(p => p.Exists).Select(p => p.FileName)).Select(p => pngFileLoader.GetPngFile(p)).Where(p => p != null).ToList(); ; - foreach (var file in newFiles.Where(p => p.Exists == false)) + var newFileNames = fileNames.Except(knownFiles.Where(p => p.Exists).Select(p => p.FileName)); + var newFileTasks = newFileNames.Select( p => pngFileLoader.GetPngFile(p)).ToList(); + + await Task.WhenAll(newFileTasks.ToArray()); + + foreach (var file in newFileTasks.Select(p => p.Result).Where(p => p != null && p.Exists == false)) { file.Exists = true; - pngFileDataSource.WritePngFile(file); + await pngFileDataSource.WritePngFile(file); logger.Info("Adding " + file.FileName); } - pngFileDataSource.CommitTransaction(); + await pngFileDataSource.CommitTransaction(); logger.Info("Rescan finished"); } } diff --git a/SDMetaTool/Processors/SummaryInfo.cs b/SDMetaTool/Processors/SummaryInfo.cs index 5cdff9b..d17f9ab 100644 --- a/SDMetaTool/Processors/SummaryInfo.cs +++ b/SDMetaTool/Processors/SummaryInfo.cs @@ -1,6 +1,7 @@ using BetterConsoleTables; using System; using System.Linq; +using System.Threading.Tasks; namespace SDMetaTool.Processors { @@ -15,10 +16,13 @@ public SummaryInfo(IFileLister fileLister, IPngFileLoader pngFileLoader) this.pngFileLoader = pngFileLoader; } - public void ProcessPngFiles(string root) + public async Task ProcessPngFiles(string root) { var fileNames = fileLister.GetList(root); - var pngFiles = fileNames.Select(p => pngFileLoader.GetPngFile(p)).Where(p => p != null).OrderBy(p => p.FileName).ToList(); + var tasks = fileNames.Select(p => pngFileLoader.GetPngFile(p)).ToList(); + await Task.WhenAll(tasks.ToArray()); + + var pngFiles = tasks.Select(p => p.Result).Where(p => p != null).OrderBy(p => p.FileName).ToList(); var distinctPrompts = pngFiles.Select(p => p.Parameters?.PromptHash).Distinct().ToList(); var distinctFullPrompts = pngFiles.Select(p => new diff --git a/SDMetaTool/Program.cs b/SDMetaTool/Program.cs index fc88028..e5aa06c 100644 --- a/SDMetaTool/Program.cs +++ b/SDMetaTool/Program.cs @@ -12,7 +12,7 @@ public class Program static async Task Main(string[] args) { var fileSystem = new FileSystem(); - using var sqliteDataSource = new SqliteDataSource(fileSystem); + await using var sqliteDataSource = new SqliteDataSource(fileSystem); var datasource = sqliteDataSource; var loader = new CachedPngFileLoader(fileSystem, new PngFileLoader(fileSystem), datasource); var fileLister = new FileLister(fileSystem); diff --git a/SDMetaUI/Pages/Index.razor b/SDMetaUI/Pages/Index.razor index 4175d93..a812bc0 100644 --- a/SDMetaUI/Pages/Index.razor +++ b/SDMetaUI/Pages/Index.razor @@ -9,7 +9,7 @@ @using SDMetaUI.Services; @using SDMetaUI.Shared; -@implements IDisposable; +@implements IAsyncDisposable; @inject IPngFileDataSource pngfileDataSource @inject Rescan rescan @@ -138,16 +138,17 @@ else }; //viewModel.Width = (await resizeListener.GetBrowserWindowSize()).Width; - LoadData(); + await LoadData(); this.StateHasChanged(); } await base.OnAfterRenderAsync(firstRender); } - private void LoadData() + private async Task LoadData() { - var data = pngfileDataSource.GetAll().Where(p => p.Exists == true).OrderByDescending(p => p.LastUpdated).Select(p => pngFileViewModelBuilder.BuildModel(p)).ToList(); + var all = await pngfileDataSource.GetAll(); + var data = all.Where(p => p.Exists).OrderByDescending(p => p.LastUpdated).Select(p => pngFileViewModelBuilder.BuildModel(p)).ToList(); viewModel.Initialize(data); } @@ -182,18 +183,18 @@ else private async Task Rescan() { - await Task.Run(() => + await Task.Run(async () => { var directory = configuration["ImageDir"]; - this.rescan.ProcessPngFiles(directory); + await this.rescan.ProcessPngFiles(directory); logger.LogInformation("Rescan done"); + await LoadData(); }); - LoadData(); } - public void Dispose() + public async ValueTask DisposeAsync() { - pngfileDataSource.Dispose(); + await pngfileDataSource.DisposeAsync(); } private async void imageDelete() @@ -202,9 +203,9 @@ else { File.Delete(this.selectedFile.FileName); await offcanvasEnd.HideAsync(); - var original = pngfileDataSource.ReadPngFile(this.selectedFile.FileName); + var original = await pngfileDataSource.ReadPngFile(this.selectedFile.FileName); original.Exists = false; - pngfileDataSource.WritePngFile(original); + await pngfileDataSource.WritePngFile(original); this.thumbnailService.Delete(this.selectedFile.FileName); this.viewModel.RemoveFile(selectedFile);