From c17fa5c485eaaaa64d606eaf0a37bec90ef934f1 Mon Sep 17 00:00:00 2001 From: ClemensFischer Date: Fri, 28 Feb 2025 18:26:59 +0100 Subject: [PATCH] Cache implementations don't throw exceptions --- Caches/FileDbCache/FileDbCache.cs | 120 +++++++--------- Caches/SQLiteCache/SQLiteCache.cs | 149 +++++++++----------- MapControl/Shared/ImageFileCache.cs | 211 ++++++++++++++++------------ 3 files changed, 229 insertions(+), 251 deletions(-) diff --git a/Caches/FileDbCache/FileDbCache.cs b/Caches/FileDbCache/FileDbCache.cs index 9ea6b723..51889f96 100644 --- a/Caches/FileDbCache/FileDbCache.cs +++ b/Caches/FileDbCache/FileDbCache.cs @@ -27,14 +27,9 @@ namespace MapControl.Caching public FileDbCache(string path, TimeSpan expirationScanFrequency) { - if (string.IsNullOrEmpty(path)) + if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(Path.GetExtension(path))) { - throw new ArgumentException($"The {nameof(path)} argument must not be null or empty.", nameof(path)); - } - - if (string.IsNullOrEmpty(Path.GetExtension(path))) - { - path = Path.Combine(path, "TileCache.fdb"); + path = Path.Combine(path ?? "", "TileCache.fdb"); } try @@ -78,22 +73,23 @@ namespace MapControl.Caching public byte[] Get(string key) { - CheckArgument(key); - byte[] value = null; - try + if (!string.IsNullOrEmpty(key)) { - var record = fileDb.GetRecordByKey(key, new string[] { valueField, expiresField }, false); - - if (record != null && (DateTime)record[1] > DateTime.UtcNow) + try { - value = (byte[])record[0]; + var record = fileDb.GetRecordByKey(key, new string[] { valueField, expiresField }, false); + + if (record != null && (DateTime)record[1] > DateTime.UtcNow) + { + value = (byte[])record[0]; + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(FileDbCache)}.Get({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(FileDbCache)}.Get({key}): {ex.Message}"); } return value; @@ -106,33 +102,34 @@ namespace MapControl.Caching public void Set(string key, byte[] value, DistributedCacheEntryOptions options) { - CheckArguments(key, value, options); - - var expiration = options.AbsoluteExpiration.HasValue - ? options.AbsoluteExpiration.Value.UtcDateTime - : DateTime.UtcNow.Add(options.AbsoluteExpirationRelativeToNow ?? options.SlidingExpiration ?? TimeSpan.FromDays(1)); - - var fieldValues = new FieldValues(3) + if (!string.IsNullOrEmpty(key) && value != null && options != null) { - { valueField, value }, - { expiresField, expiration } - }; + var expiration = options.AbsoluteExpiration.HasValue + ? options.AbsoluteExpiration.Value.UtcDateTime + : DateTime.UtcNow.Add(options.AbsoluteExpirationRelativeToNow ?? options.SlidingExpiration ?? TimeSpan.FromDays(1)); - try - { - if (fileDb.GetRecordByKey(key, new string[0], false) != null) + var fieldValues = new FieldValues(3) { - fileDb.UpdateRecordByKey(key, fieldValues); - } - else + { valueField, value }, + { expiresField, expiration } + }; + + try { - fieldValues.Add(keyField, key); - fileDb.AddRecord(fieldValues); + if (fileDb.GetRecordByKey(key, new string[0], false) != null) + { + fileDb.UpdateRecordByKey(key, fieldValues); + } + else + { + fieldValues.Add(keyField, key); + fileDb.AddRecord(fieldValues); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(FileDbCache)}.Set({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(FileDbCache)}.Set({key}): {ex.Message}"); } } @@ -145,25 +142,25 @@ namespace MapControl.Caching public void Refresh(string key) { - throw new NotSupportedException(); } public Task RefreshAsync(string key, CancellationToken token = default) { - throw new NotSupportedException(); + return Task.CompletedTask; } public void Remove(string key) { - CheckArgument(key); - - try + if (!string.IsNullOrEmpty(key)) { - fileDb.DeleteRecordByKey(key); - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(FileDbCache)}.Remove({key}): {ex.Message}"); + try + { + fileDb.DeleteRecordByKey(key); + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(FileDbCache)}.Remove({key}): {ex.Message}"); + } } } @@ -185,28 +182,5 @@ namespace MapControl.Caching Debug.WriteLine($"{nameof(FileDbCache)}: Deleted {deleted} expired items"); } } - - private static void CheckArgument(string key) - { - if (string.IsNullOrEmpty(key)) - { - throw new ArgumentException($"The {nameof(key)} argument must not be null or empty.", nameof(key)); - } - } - - private static void CheckArguments(string key, byte[] value, DistributedCacheEntryOptions options) - { - CheckArgument(key); - - if (value == null) - { - throw new ArgumentNullException(nameof(value), $"The {nameof(value)} argument must not be null."); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options), $"The {nameof(options)} argument must not be null."); - } - } } } diff --git a/Caches/SQLiteCache/SQLiteCache.cs b/Caches/SQLiteCache/SQLiteCache.cs index 4cb2a243..7284f208 100644 --- a/Caches/SQLiteCache/SQLiteCache.cs +++ b/Caches/SQLiteCache/SQLiteCache.cs @@ -23,14 +23,9 @@ namespace MapControl.Caching public SQLiteCache(string path, TimeSpan expirationScanFrequency) { - if (string.IsNullOrEmpty(path)) + if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(Path.GetExtension(path))) { - throw new ArgumentException($"The {nameof(path)} argument must not be null or empty.", nameof(path)); - } - - if (string.IsNullOrEmpty(Path.GetExtension(path))) - { - path = Path.Combine(path, "TileCache.sqlite"); + path = Path.Combine(path ?? "", "TileCache.sqlite"); } connection = new SQLiteConnection("Data Source=" + path); @@ -62,20 +57,21 @@ namespace MapControl.Caching public byte[] Get(string key) { - CheckArgument(key); - byte[] value = null; - try + if (!string.IsNullOrEmpty(key)) { - using (var command = GetItemCommand(key)) + try { - value = (byte[])command.ExecuteScalar(); + using (var command = GetItemCommand(key)) + { + value = (byte[])command.ExecuteScalar(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(SQLiteCache)}.Get({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(SQLiteCache)}.Get({key}): {ex.Message}"); } return value; @@ -83,20 +79,21 @@ namespace MapControl.Caching public async Task GetAsync(string key, CancellationToken token = default) { - CheckArgument(key); - byte[] value = null; - try + if (!string.IsNullOrEmpty(key)) { - using (var command = GetItemCommand(key)) + try { - value = (byte[])await command.ExecuteScalarAsync(); + using (var command = GetItemCommand(key)) + { + value = (byte[])await command.ExecuteScalarAsync(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(SQLiteCache)}.GetAsync({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(SQLiteCache)}.GetAsync({key}): {ex.Message}"); } return value; @@ -104,79 +101,82 @@ namespace MapControl.Caching public void Set(string key, byte[] value, DistributedCacheEntryOptions options) { - CheckArguments(key, value, options); - - try + if (!string.IsNullOrEmpty(key) && value != null && options != null) { - using (var command = SetItemCommand(key, value, options)) + try { - command.ExecuteNonQuery(); + using (var command = SetItemCommand(key, value, options)) + { + command.ExecuteNonQuery(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(SQLiteCache)}.Set({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(SQLiteCache)}.Set({key}): {ex.Message}"); } } public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default) { - CheckArguments(key, value, options); - - try + if (!string.IsNullOrEmpty(key) && value != null && options != null) { - using (var command = SetItemCommand(key, value, options)) + try { - await command.ExecuteNonQueryAsync(token); + using (var command = SetItemCommand(key, value, options)) + { + await command.ExecuteNonQueryAsync(token); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(SQLiteCache)}.SetAsync({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(SQLiteCache)}.SetAsync({key}): {ex.Message}"); } } public void Refresh(string key) { - throw new NotSupportedException(); } public Task RefreshAsync(string key, CancellationToken token = default) { - throw new NotSupportedException(); + return Task.CompletedTask; } public void Remove(string key) { - CheckArgument(key); - - try + if (!string.IsNullOrEmpty(key)) { - using (var command = DeleteItemCommand(key)) + try { - command.ExecuteNonQuery(); + using (var command = DeleteItemCommand(key)) + { + command.ExecuteNonQuery(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(SQLiteCache)}.Remove({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(SQLiteCache)}.Remove({key}): {ex.Message}"); } } public async Task RemoveAsync(string key, CancellationToken token = default) { - CheckArgument(key); - - try + if (!string.IsNullOrEmpty(key)) { - using (var command = DeleteItemCommand(key)) + try { - await command.ExecuteNonQueryAsync(); + using (var command = DeleteItemCommand(key)) + { + await command.ExecuteNonQueryAsync(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(SQLiteCache)}.RemoveAsync({key}): {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(SQLiteCache)}.RemoveAsync({key}): {ex.Message}"); } } @@ -225,28 +225,5 @@ namespace MapControl.Caching command.Parameters.AddWithValue("@exp", DateTimeOffset.UtcNow.Ticks); return command; } - - private static void CheckArgument(string key) - { - if (string.IsNullOrEmpty(key)) - { - throw new ArgumentException($"The {nameof(key)} argument must not be null or empty.", nameof(key)); - } - } - - private static void CheckArguments(string key, byte[] value, DistributedCacheEntryOptions options) - { - CheckArgument(key); - - if (value == null) - { - throw new ArgumentNullException(nameof(value), $"The {nameof(value)} argument must not be null."); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options), $"The {nameof(options)} argument must not be null."); - } - } } } diff --git a/MapControl/Shared/ImageFileCache.cs b/MapControl/Shared/ImageFileCache.cs index 8a42887a..5bb188e9 100644 --- a/MapControl/Shared/ImageFileCache.cs +++ b/MapControl/Shared/ImageFileCache.cs @@ -29,7 +29,7 @@ namespace MapControl.Caching { if (string.IsNullOrEmpty(path)) { - throw new ArgumentException($"The {nameof(path)} argument must not be null or empty.", nameof(path)); + path = "TileCache"; } rootDirectory = new DirectoryInfo(path); @@ -56,158 +56,185 @@ namespace MapControl.Caching public byte[] Get(string key) { - var buffer = memoryCache.Get(key); + byte[] value = null; - if (buffer == null) + if (!string.IsNullOrEmpty(key)) { - var file = GetFile(key); + value = memoryCache.Get(key); - try + if (value == null) { - if (file != null && file.Exists && file.CreationTime > DateTime.Now) + var file = GetFile(key); + + try { - buffer = ReadAllBytes(file); + if (file != null && file.Exists && file.CreationTime > DateTime.Now) + { + value = ReadAllBytes(file); - var options = new DistributedCacheEntryOptions { AbsoluteExpiration = file.CreationTime }; + var options = new DistributedCacheEntryOptions { AbsoluteExpiration = file.CreationTime }; - memoryCache.Set(key, buffer, options); + memoryCache.Set(key, value, options); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(ImageFileCache)}: Failed reading {file.FullName}: {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(ImageFileCache)}: Failed reading {file.FullName}: {ex.Message}"); } } - return buffer; + return value; } public async Task GetAsync(string key, CancellationToken token = default) { - var buffer = await memoryCache.GetAsync(key, token).ConfigureAwait(false); + byte[] value = null; - if (buffer == null) + if (!string.IsNullOrEmpty(key)) { + value = await memoryCache.GetAsync(key, token).ConfigureAwait(false); + + if (value == null) + { + var file = GetFile(key); + + try + { + if (file != null && file.Exists && file.CreationTime > DateTime.Now && !token.IsCancellationRequested) + { + value = await ReadAllBytes(file, token).ConfigureAwait(false); + + var options = new DistributedCacheEntryOptions { AbsoluteExpiration = file.CreationTime }; + + await memoryCache.SetAsync(key, value, options, token).ConfigureAwait(false); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(ImageFileCache)}: Failed reading {file.FullName}: {ex.Message}"); + } + } + } + + return value; + } + + public void Set(string key, byte[] value, DistributedCacheEntryOptions options) + { + if (!string.IsNullOrEmpty(key) && value != null && options != null) + { + memoryCache.Set(key, value, options); + var file = GetFile(key); try { - if (file != null && file.Exists && file.CreationTime > DateTime.Now && !token.IsCancellationRequested) + if (file != null && value?.Length > 0) { - buffer = await ReadAllBytes(file, token).ConfigureAwait(false); + file.Directory.Create(); - var options = new DistributedCacheEntryOptions { AbsoluteExpiration = file.CreationTime }; + using (var stream = file.Create()) + { + stream.Write(value, 0, value.Length); + } - await memoryCache.SetAsync(key, buffer, options, token).ConfigureAwait(false); + SetExpiration(file, options); } } catch (Exception ex) { - buffer = null; - Debug.WriteLine($"{nameof(ImageFileCache)}: Failed reading {file.FullName}: {ex.Message}"); + Debug.WriteLine($"{nameof(ImageFileCache)}: Failed writing {file.FullName}: {ex.Message}"); } } - - return buffer; - } - - public void Set(string key, byte[] buffer, DistributedCacheEntryOptions options) - { - memoryCache.Set(key, buffer, options); - - var file = GetFile(key); - - try - { - if (file != null && buffer?.Length > 0) - { - file.Directory.Create(); - - using (var stream = file.Create()) - { - stream.Write(buffer, 0, buffer.Length); - } - - SetExpiration(file, options); - } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(ImageFileCache)}: Failed writing {file.FullName}: {ex.Message}"); - } } - public async Task SetAsync(string key, byte[] buffer, DistributedCacheEntryOptions options, CancellationToken token = default) + public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default) { - await memoryCache.SetAsync(key, buffer, options, token).ConfigureAwait(false); - - var file = GetFile(key); - - try + if (!string.IsNullOrEmpty(key) && value != null && options != null) { - if (file != null && buffer?.Length > 0 && !token.IsCancellationRequested) + await memoryCache.SetAsync(key, value, options, token).ConfigureAwait(false); + + var file = GetFile(key); + + try { - file.Directory.Create(); - - using (var stream = file.Create()) + if (file != null && value?.Length > 0 && !token.IsCancellationRequested) { - await stream.WriteAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false); - } + file.Directory.Create(); - SetExpiration(file, options); + using (var stream = file.Create()) + { + await stream.WriteAsync(value, 0, value.Length, token).ConfigureAwait(false); + } + + SetExpiration(file, options); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(ImageFileCache)}: Failed writing {file.FullName}: {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(ImageFileCache)}: Failed writing {file.FullName}: {ex.Message}"); } } public void Refresh(string key) { - memoryCache.Refresh(key); + if (!string.IsNullOrEmpty(key)) + { + memoryCache.Refresh(key); + } } - public Task RefreshAsync(string key, CancellationToken token = default) + public async Task RefreshAsync(string key, CancellationToken token = default) { - return memoryCache.RefreshAsync(key, token); + if (!string.IsNullOrEmpty(key)) + { + await memoryCache.RefreshAsync(key, token); + } } public void Remove(string key) { - memoryCache.Remove(key); - - var file = GetFile(key); - - try + if (!string.IsNullOrEmpty(key)) { - if (file != null && file.Exists) + memoryCache.Remove(key); + + var file = GetFile(key); + + try { - file.Delete(); + if (file != null && file.Exists) + { + file.Delete(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(ImageFileCache)}: Failed deleting {file.FullName}: {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(ImageFileCache)}: Failed deleting {file.FullName}: {ex.Message}"); } } public async Task RemoveAsync(string key, CancellationToken token = default) { - await memoryCache.RemoveAsync(key, token); - - var file = GetFile(key); - - try + if (!string.IsNullOrEmpty(key)) { - if (file != null && file.Exists && !token.IsCancellationRequested) + await memoryCache.RemoveAsync(key, token); + + var file = GetFile(key); + + try { - file.Delete(); + if (file != null && file.Exists && !token.IsCancellationRequested) + { + file.Delete(); + } + } + catch (Exception ex) + { + Debug.WriteLine($"{nameof(ImageFileCache)}: Failed deleting {file.FullName}: {ex.Message}"); } - } - catch (Exception ex) - { - Debug.WriteLine($"{nameof(ImageFileCache)}: Failed deleting {file.FullName}: {ex.Message}"); } }