diff --git a/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt index 459ea8776..63d0f81e9 100644 --- a/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt @@ -1,4 +1,13 @@ -Version 8.3.2 +Version 9.0.0 +Availability: .NET 9, .NET 8, .NET 6 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies to latest and greatest with respect to TFMs +  +# New Features +- ADDED support for System.Threading.Lock object that targets .NET TFM prior to .NET 9 (credits to Mark Cilia Vincenti, https://github.com/MarkCiliaVincenti/Backport.System.Threading.Lock) +  +Version 8.3.2 Availability: .NET 8, .NET 6 and .NET Standard 2.0   # ALM diff --git a/CHANGELOG.md b/CHANGELOG.md index a9fbb4934..c0b0f6f57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ New features: - FailureConverter class in the Cuemon.Extensions.Newtonsoft.Json.Converters namespace to convert FailureConverter to JSON - FailureConverter class in the Cuemon.Extensions.Text.Json.Converters namespace to convert FailureConverter to JSON - FailureConverter class in the Cuemon.Xml.Serialization.Converters namespace to convert FailureConverter to XML +- Support for System.Threading.Lock object that targets TFMs prior to .NET 9 (credits to Mark Cilia Vincenti, https://github.com/MarkCiliaVincenti/Backport.System.Threading.Lock) ### Changed diff --git a/src/Cuemon.Core/Cuemon.Core.csproj b/src/Cuemon.Core/Cuemon.Core.csproj index 6807e66c6..0a1710f99 100644 --- a/src/Cuemon.Core/Cuemon.Core.csproj +++ b/src/Cuemon.Core/Cuemon.Core.csproj @@ -13,8 +13,4 @@ action-factory bit-unit byte-unit binary-prefix decimal-prefix prefix-multiple multiple-table calculator configure configure-revert configure-exchange configurable condition options-pattern data-reader decorator delimited-string disposable finalize-disposable safe-invoke safe-invoke-async func-factory patterns reference-project clean-architecture clean-code task-action-factory task-func-factory template template-factory time-range time-unit validator guard text-encoding parser-factory security aes-cryptor cyclic-redundancy-check fowler-noll-vo-hash hash-factory hash-result hmac-message-digest hmac-secure-hash-algorithm keyed-crypto-hash keyed-crypto-algorithm message-digest non-crypto-algorithm secure-hash-algorithm unkeyed-crypto-hash - - - - diff --git a/src/Cuemon.Core/Runtime/Dependency.cs b/src/Cuemon.Core/Runtime/Dependency.cs index f37c74f6b..5b4bdb63d 100644 --- a/src/Cuemon.Core/Runtime/Dependency.cs +++ b/src/Cuemon.Core/Runtime/Dependency.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; namespace Cuemon.Runtime @@ -13,7 +12,7 @@ public abstract class Dependency : IDependency { private IEnumerable _watchers; private readonly Func, IEnumerable> _watchersHandler; - private readonly Lock _locker = new(); + private readonly object _locker = new(); /// /// Initializes a new instance of the class. diff --git a/src/Cuemon.Core/Runtime/FileWatcher.cs b/src/Cuemon.Core/Runtime/FileWatcher.cs index 851420ba9..b40c2e7ab 100644 --- a/src/Cuemon.Core/Runtime/FileWatcher.cs +++ b/src/Cuemon.Core/Runtime/FileWatcher.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Threading; using System.Threading.Tasks; using Cuemon.Security; @@ -12,7 +11,7 @@ namespace Cuemon.Runtime /// public class FileWatcher : Watcher { - private readonly Lock _locker = new(); + private readonly object _locker = new(); /// /// Initializes a new instance of the class. diff --git a/src/Cuemon.Core/Runtime/Watcher.cs b/src/Cuemon.Core/Runtime/Watcher.cs index a0bbee15f..6f3f5f6d5 100644 --- a/src/Cuemon.Core/Runtime/Watcher.cs +++ b/src/Cuemon.Core/Runtime/Watcher.cs @@ -10,7 +10,7 @@ namespace Cuemon.Runtime /// public abstract class Watcher : Disposable, IWatcher { - private readonly Lock _locker = new(); + private readonly object _locker = new(); private Timer _watcherTimer; private Timer _watcherPostponingTimer; diff --git a/src/Cuemon.Core/Threading/Lock.cs b/src/Cuemon.Core/Threading/Lock.cs deleted file mode 100644 index 823925571..000000000 --- a/src/Cuemon.Core/Threading/Lock.cs +++ /dev/null @@ -1,139 +0,0 @@ -// Credit: Mark Cilia Vincenti, 2024 -// Taken from: https://github.com/MarkCiliaVincenti/Backport.System.Threading.Lock -// NuGet package: https://www.nuget.org/packages/Backport.System.Threading.Lock - -using System.Runtime.CompilerServices; -#if NET9_0_OR_GREATER -[assembly: TypeForwardedTo(typeof(System.Threading.Lock))] -#else -namespace System.Threading -{ - /// - /// A backport of .NET 9.0+'s System.Threading.Lock. Provides a way to get mutual exclusion in regions of code between different threads. - /// A lock may be held by one thread at a time. - /// - /// - /// Threads that cannot immediately enter the lock may wait for the lock to be exited or until a specified timeout. A thread - /// that holds a lock may enter the lock repeatedly without exiting it, such as recursively, in which case the thread should - /// eventually exit the lock the same number of times to fully exit the lock and allow other threads to enter the lock. - /// - public sealed class Lock - { -#pragma warning disable CS9216 // A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement. - /// - /// - /// - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public void Enter() => Monitor.Enter(this); - - /// - /// - /// - /// - /// - /// - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public bool TryEnter() => Monitor.TryEnter(this); - - /// - /// - /// - /// - /// - /// - /// - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public bool TryEnter(TimeSpan timeout) => Monitor.TryEnter(this, timeout); - - /// - /// - /// - /// - /// - /// - /// - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public bool TryEnter(int millisecondsTimeout) => Monitor.TryEnter(this, millisecondsTimeout); - - /// - /// - /// - /// - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public void Exit() => Monitor.Exit(this); - - /// - /// Determines whether the current thread holds this lock. - /// - /// - /// true if the current thread holds this lock; otherwise, false. - /// - /// -#if !PRE_NETSTANDARD - public bool IsHeldByCurrentThread => Monitor.IsEntered(this); -#else - public bool IsHeldByCurrentThread => throw new NotSupportedException("IsHeldByCurrentThread is only supported on .NET Framework 4.5 or greater."); -#endif -#pragma warning restore CS9216 // A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement. - - /// - /// Enters the lock and returns a that may be disposed to exit the lock. Once the method returns, - /// the calling thread would be the only thread that holds the lock. This method is intended to be used along with a - /// language construct that would automatically dispose the , such as with the C# using statement. - /// - /// - /// A that may be disposed to exit the lock. - /// - /// - /// If the lock cannot be entered immediately, the calling thread waits for the lock to be exited. If the lock is - /// already held by the calling thread, the lock is entered again. The calling thread should exit the lock, such as by - /// disposing the returned , as many times as it had entered the lock to fully exit the lock and - /// allow other threads to enter the lock. - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public Scope EnterScope() - { - Enter(); - return new Scope(this); - } - - /// - /// A disposable structure that is returned by , which when disposed, exits the lock. - /// - public ref struct Scope(Lock @lock) - { - /// - /// Exits the lock. - /// - /// - /// If the calling thread holds the lock multiple times, such as recursively, the lock is exited only once. The - /// calling thread should ensure that each enter is matched with an exit. - /// - /// - /// The calling thread does not hold the lock. - /// -#if !PRE_NETSTANDARD - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - public readonly void Dispose() => @lock.Exit(); - } - } -} -#endif diff --git a/src/Cuemon.Data/BulkCopyDataReader.cs b/src/Cuemon.Data/BulkCopyDataReader.cs index a071ad876..c3fb3225b 100644 --- a/src/Cuemon.Data/BulkCopyDataReader.cs +++ b/src/Cuemon.Data/BulkCopyDataReader.cs @@ -6,7 +6,6 @@ using System.Globalization; using System.Linq; using System.Text; -using System.Threading; namespace Cuemon.Data { @@ -15,7 +14,7 @@ namespace Cuemon.Data /// public sealed class BulkCopyDataReader : DbDataReader { - private static readonly Lock PadLock = new(); + private static readonly object PadLock = new(); private IOrderedDictionary _defaultFields; /// diff --git a/src/Cuemon.Data/DatabaseWatcher.cs b/src/Cuemon.Data/DatabaseWatcher.cs index bcab2bbf4..9aeb3d248 100644 --- a/src/Cuemon.Data/DatabaseWatcher.cs +++ b/src/Cuemon.Data/DatabaseWatcher.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; -using System.Threading; using System.Threading.Tasks; using Cuemon.Runtime; using Cuemon.Security; @@ -15,7 +14,7 @@ namespace Cuemon.Data /// public class DatabaseWatcher : Watcher { - private readonly Lock _locker = new(); + private readonly object _locker = new(); /// /// Initializes a new instance of the class. diff --git a/src/Cuemon.Extensions.AspNetCore.Newtonsoft.Json/Bootstrapper.cs b/src/Cuemon.Extensions.AspNetCore.Newtonsoft.Json/Bootstrapper.cs index 9f9ed8813..60cda82c9 100644 --- a/src/Cuemon.Extensions.AspNetCore.Newtonsoft.Json/Bootstrapper.cs +++ b/src/Cuemon.Extensions.AspNetCore.Newtonsoft.Json/Bootstrapper.cs @@ -1,12 +1,11 @@ using Cuemon.Extensions.AspNetCore.Newtonsoft.Json.Converters; using Cuemon.Extensions.Newtonsoft.Json.Formatters; -using System.Threading; namespace Cuemon.Extensions.AspNetCore.Newtonsoft.Json { internal static class Bootstrapper { - private static readonly Lock PadLock = new(); + private static readonly object PadLock = new(); private static bool _initialized; internal static void Initialize() diff --git a/src/Cuemon.Extensions.AspNetCore.Text.Json/Bootstrapper.cs b/src/Cuemon.Extensions.AspNetCore.Text.Json/Bootstrapper.cs index 8da6adf94..50f33939b 100644 --- a/src/Cuemon.Extensions.AspNetCore.Text.Json/Bootstrapper.cs +++ b/src/Cuemon.Extensions.AspNetCore.Text.Json/Bootstrapper.cs @@ -1,12 +1,11 @@ using Cuemon.Extensions.AspNetCore.Text.Json.Converters; using Cuemon.Extensions.Text.Json.Formatters; -using System.Threading; namespace Cuemon.Extensions.AspNetCore.Text.Json { internal static class Bootstrapper { - private static readonly Lock PadLock = new(); + private static readonly object PadLock = new(); private static bool _initialized; internal static void Initialize() diff --git a/src/Cuemon.Extensions.AspNetCore.Xml/Bootstrapper.cs b/src/Cuemon.Extensions.AspNetCore.Xml/Bootstrapper.cs index c21d48bbd..4da21b799 100644 --- a/src/Cuemon.Extensions.AspNetCore.Xml/Bootstrapper.cs +++ b/src/Cuemon.Extensions.AspNetCore.Xml/Bootstrapper.cs @@ -1,12 +1,11 @@ using Cuemon.Extensions.AspNetCore.Xml.Converters; using Cuemon.Xml.Serialization.Formatters; -using System.Threading; namespace Cuemon.Extensions.AspNetCore.Xml { internal static class Bootstrapper { - private static readonly Lock PadLock = new(); + private static readonly object PadLock = new(); private static bool _initialized; internal static void Initialize() diff --git a/src/Cuemon.Extensions.Net/Http/SlimHttpClientFactory.cs b/src/Cuemon.Extensions.Net/Http/SlimHttpClientFactory.cs index 3a5fe7bb5..66f6b44cb 100644 --- a/src/Cuemon.Extensions.Net/Http/SlimHttpClientFactory.cs +++ b/src/Cuemon.Extensions.Net/Http/SlimHttpClientFactory.cs @@ -29,7 +29,7 @@ public class SlimHttpClientFactory : IHttpClientFactory private readonly ConcurrentDictionary> _activeHandlers = new(); private readonly ConcurrentQueue _expiredHandlers = new(); private readonly Func _handlerFactory; - private readonly Lock _locker = new(); + private readonly object _locker = new(); private readonly SlimHttpClientFactoryOptions _options; internal static readonly TimeSpan ExpirationTimerDueTime = TimeSpan.FromSeconds(15); private Timer _expirationTimer; diff --git a/src/Cuemon.Extensions.Newtonsoft.Json/Formatters/NewtonsoftJsonFormatterOptions.cs b/src/Cuemon.Extensions.Newtonsoft.Json/Formatters/NewtonsoftJsonFormatterOptions.cs index 61ae8895e..2c6fe74f8 100644 --- a/src/Cuemon.Extensions.Newtonsoft.Json/Formatters/NewtonsoftJsonFormatterOptions.cs +++ b/src/Cuemon.Extensions.Newtonsoft.Json/Formatters/NewtonsoftJsonFormatterOptions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Net.Http.Headers; using System.Reflection; -using System.Threading; using Cuemon.Configuration; using Cuemon.Diagnostics; using Cuemon.Extensions.Newtonsoft.Json.Converters; @@ -17,7 +16,7 @@ namespace Cuemon.Extensions.Newtonsoft.Json.Formatters /// public class NewtonsoftJsonFormatterOptions : IExceptionDescriptorOptions, IContentNegotiation, IValidatableParameterObject { - private readonly Lock _locker = new(); + private readonly object _locker = new(); private bool _refreshed; /// diff --git a/src/Cuemon.Extensions.Runtime.Caching/CacheEnumerableExtensions.cs b/src/Cuemon.Extensions.Runtime.Caching/CacheEnumerableExtensions.cs index 26f2e7cd0..7244291e1 100644 --- a/src/Cuemon.Extensions.Runtime.Caching/CacheEnumerableExtensions.cs +++ b/src/Cuemon.Extensions.Runtime.Caching/CacheEnumerableExtensions.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Linq; using System.Reflection; -using System.Threading; using Cuemon.Collections.Generic; using Cuemon.Reflection; using Cuemon.Runtime; @@ -707,7 +706,7 @@ public static Func Memoize(ICacheEnumerable cache, string key, CacheInvalidation invalidation, FuncFactory valueFactory) where TTuple : Template { diff --git a/src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatterOptions.cs b/src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatterOptions.cs index fc6fb782c..775435f73 100644 --- a/src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatterOptions.cs +++ b/src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatterOptions.cs @@ -4,7 +4,6 @@ using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Serialization; -using System.Threading; using Cuemon.Configuration; using Cuemon.Diagnostics; using Cuemon.Extensions.Text.Json.Converters; @@ -17,7 +16,7 @@ namespace Cuemon.Extensions.Text.Json.Formatters /// public class JsonFormatterOptions : IContentNegotiation, IExceptionDescriptorOptions, IValidatableParameterObject { - private readonly Lock _locker = new(); + private readonly object _locker = new(); private bool _refreshed; /// diff --git a/src/Cuemon.Extensions.Threading/Cuemon.Extensions.Threading.csproj b/src/Cuemon.Extensions.Threading/Cuemon.Extensions.Threading.csproj index 82273dce8..c68df8d90 100644 --- a/src/Cuemon.Extensions.Threading/Cuemon.Extensions.Threading.csproj +++ b/src/Cuemon.Extensions.Threading/Cuemon.Extensions.Threading.csproj @@ -13,4 +13,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/src/Cuemon.Extensions.YamlDotNet/Formatters/YamlFormatterOptions.cs b/src/Cuemon.Extensions.YamlDotNet/Formatters/YamlFormatterOptions.cs index 866f45476..baeb215f3 100644 --- a/src/Cuemon.Extensions.YamlDotNet/Formatters/YamlFormatterOptions.cs +++ b/src/Cuemon.Extensions.YamlDotNet/Formatters/YamlFormatterOptions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; -using System.Threading; using Cuemon.Configuration; using Cuemon.Diagnostics; using Cuemon.Extensions.YamlDotNet.Converters; @@ -16,7 +15,7 @@ namespace Cuemon.Extensions.YamlDotNet.Formatters /// public class YamlFormatterOptions : EncodingOptions, IExceptionDescriptorOptions, IContentNegotiation, IValidatableParameterObject { - private readonly Lock _locker = new(); + private readonly object _locker = new(); private bool _refreshed; /// diff --git a/src/Cuemon.Xml/Serialization/Formatters/XmlFormatterOptions.cs b/src/Cuemon.Xml/Serialization/Formatters/XmlFormatterOptions.cs index f354cade7..b44734460 100644 --- a/src/Cuemon.Xml/Serialization/Formatters/XmlFormatterOptions.cs +++ b/src/Cuemon.Xml/Serialization/Formatters/XmlFormatterOptions.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Net.Http.Headers; -using System.Threading; using Cuemon.Configuration; using Cuemon.Diagnostics; using Cuemon.Net.Http; @@ -14,7 +13,7 @@ namespace Cuemon.Xml.Serialization.Formatters /// public class XmlFormatterOptions : IExceptionDescriptorOptions, IContentNegotiation, IValidatableParameterObject { - private readonly Lock _locker = new(); + private readonly object _locker = new(); private bool _refreshed; ///