From dbfa515546ec6c4dd37dd5fd69538a31e0a9fa25 Mon Sep 17 00:00:00 2001 From: "Darrin W. Cullop" Date: Fri, 10 Apr 2026 00:30:31 -0700 Subject: [PATCH] Refactor SwappableLock to support NET9+ Lock type Add Lock overloads for SwappableLock.SwapTo and constructor to support the new System.Threading.Lock type on .NET 9+. Uses #if NET9_0_OR_GREATER conditional compilation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/DynamicData/Internal/SwappableLock.cs | 56 ++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/DynamicData/Internal/SwappableLock.cs b/src/DynamicData/Internal/SwappableLock.cs index 267607e9..5f1f4759 100644 --- a/src/DynamicData/Internal/SwappableLock.cs +++ b/src/DynamicData/Internal/SwappableLock.cs @@ -18,23 +18,73 @@ public static SwappableLock CreateAndEnter(object gate) return result; } +#if NET9_0_OR_GREATER + public static SwappableLock CreateAndEnter(Lock gate) + { + gate.Enter(); + return new SwappableLock() { _lockGate = gate }; + } +#endif + public void SwapTo(object gate) { +#if NET9_0_OR_GREATER + if (_gate is null && _lockGate is null) + throw new InvalidOperationException("Lock is not initialized"); +#else if (_gate is null) throw new InvalidOperationException("Lock is not initialized"); +#endif var hasNewLock = false; Monitor.Enter(gate, ref hasNewLock); +#if NET9_0_OR_GREATER + if (_lockGate is not null) + { + _lockGate.Exit(); + _lockGate = null; + } + else +#endif if (_hasLock) - Monitor.Exit(_gate); + { + Monitor.Exit(_gate!); + } _hasLock = hasNewLock; _gate = gate; } +#if NET9_0_OR_GREATER + public void SwapTo(Lock gate) + { + if (_lockGate is null && _gate is null) + throw new InvalidOperationException("Lock is not initialized"); + + gate.Enter(); + + if (_lockGate is not null) + _lockGate.Exit(); + else if (_hasLock) + Monitor.Exit(_gate!); + + _lockGate = gate; + _hasLock = false; + _gate = null; + } +#endif + public void Dispose() { +#if NET9_0_OR_GREATER + if (_lockGate is not null) + { + _lockGate.Exit(); + _lockGate = null; + } + else +#endif if (_hasLock && (_gate is not null)) { Monitor.Exit(_gate); @@ -45,4 +95,8 @@ public void Dispose() private bool _hasLock; private object? _gate; + +#if NET9_0_OR_GREATER + private Lock? _lockGate; +#endif }