diff --git a/ScreenCapture.NET.DX11/DX11ScreenCapture.cs b/ScreenCapture.NET.DX11/DX11ScreenCapture.cs index c5df93d..8a83817 100644 --- a/ScreenCapture.NET.DX11/DX11ScreenCapture.cs +++ b/ScreenCapture.NET.DX11/DX11ScreenCapture.cs @@ -35,7 +35,8 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture #region Properties & Fields - private readonly object _captureLock = new(); + private readonly Lock _captureLock = new(); + private readonly Lock _texturesLock = new(); private readonly bool _useNewDuplicationAdapter; @@ -140,7 +141,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture { if (_context == null) return; - lock (_textures) + lock (_texturesLock) { if (!_textures.TryGetValue(captureZone, out ZoneTextures? textures)) return; @@ -258,7 +259,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture { CaptureZone captureZone = base.RegisterCaptureZone(x, y, width, height, downscaleLevel); - lock (_textures) + lock (_texturesLock) InitializeCaptureZone(captureZone); return captureZone; @@ -269,7 +270,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture { if (!base.UnregisterCaptureZone(captureZone)) return false; - lock (_textures) + lock (_texturesLock) { if (_textures.TryGetValue(captureZone, out ZoneTextures? textures)) { @@ -291,7 +292,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture //TODO DarthAffe 01.05.2022: For now just reinitialize the zone in that case, but this could be optimized to only recreate the textures needed. if ((width != null) || (height != null) || (downscaleLevel != null)) { - lock (_textures) + lock (_texturesLock) { if (_textures.TryGetValue(captureZone, out ZoneTextures? textures)) { @@ -383,7 +384,7 @@ public sealed class DX11ScreenCapture : AbstractScreenCapture base.Restart(); lock (_captureLock) - lock (_textures) + lock (_texturesLock) { try { diff --git a/ScreenCapture.NET.DX11/ScreenCapture.NET.DX11.csproj b/ScreenCapture.NET.DX11/ScreenCapture.NET.DX11.csproj index 6e0b0b3..cb93941 100644 --- a/ScreenCapture.NET.DX11/ScreenCapture.NET.DX11.csproj +++ b/ScreenCapture.NET.DX11/ScreenCapture.NET.DX11.csproj @@ -1,6 +1,6 @@  - net8.0 + net8.0;net9.0 win-x64 latest enable @@ -54,6 +54,10 @@ $(DefineConstants);RELEASE + + + + True diff --git a/ScreenCapture.NET.DX9/DX9ScreenCapture.cs b/ScreenCapture.NET.DX9/DX9ScreenCapture.cs index 94ffcee..281235a 100644 --- a/ScreenCapture.NET.DX9/DX9ScreenCapture.cs +++ b/ScreenCapture.NET.DX9/DX9ScreenCapture.cs @@ -17,7 +17,7 @@ public sealed class DX9ScreenCapture : AbstractScreenCapture { #region Properties & Fields - private readonly object _captureLock = new(); + private readonly Lock _captureLock = new(); private readonly IDirect3D9 _direct3D9; private IDirect3DDevice9? _device; diff --git a/ScreenCapture.NET.DX9/ScreenCapture.NET.DX9.csproj b/ScreenCapture.NET.DX9/ScreenCapture.NET.DX9.csproj index cdbdd8e..4ae68e2 100644 --- a/ScreenCapture.NET.DX9/ScreenCapture.NET.DX9.csproj +++ b/ScreenCapture.NET.DX9/ScreenCapture.NET.DX9.csproj @@ -1,6 +1,6 @@  - net8.0 + net8.0;net9.0 win-x64 latest enable @@ -54,6 +54,10 @@ $(DefineConstants);RELEASE + + + + True diff --git a/ScreenCapture.NET.X11/ScreenCapture.NET.X11.csproj b/ScreenCapture.NET.X11/ScreenCapture.NET.X11.csproj index 5cdcb03..0453143 100644 --- a/ScreenCapture.NET.X11/ScreenCapture.NET.X11.csproj +++ b/ScreenCapture.NET.X11/ScreenCapture.NET.X11.csproj @@ -1,6 +1,6 @@  - net8.0 + net8.0;net9.0 linux-x64 latest enable @@ -54,6 +54,10 @@ $(DefineConstants);RELEASE + + + + True diff --git a/ScreenCapture.NET.X11/X11ScreenCapture.cs b/ScreenCapture.NET.X11/X11ScreenCapture.cs index c797c75..9ec51f6 100644 --- a/ScreenCapture.NET.X11/X11ScreenCapture.cs +++ b/ScreenCapture.NET.X11/X11ScreenCapture.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using HPPH; namespace ScreenCapture.NET; @@ -14,7 +15,7 @@ public sealed class X11ScreenCapture : AbstractScreenCapture { #region Properties & Fields - private readonly object _captureLock = new(); + private readonly Lock _captureLock = new(); private nint _display; private nint _drawable; @@ -62,12 +63,11 @@ public sealed class X11ScreenCapture : AbstractScreenCapture protected override void PerformCaptureZoneUpdate(CaptureZone captureZone, Span buffer) { using IDisposable @lock = captureZone.Lock(); - { - if (captureZone.DownscaleLevel == 0) - CopyZone(captureZone, buffer); - else - DownscaleZone(captureZone, buffer); - } + + if (captureZone.DownscaleLevel == 0) + CopyZone(captureZone, buffer); + else + DownscaleZone(captureZone, buffer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/ScreenCapture.NET/Compatibility/Lock.cs b/ScreenCapture.NET/Compatibility/Lock.cs new file mode 100644 index 0000000..49b23e5 --- /dev/null +++ b/ScreenCapture.NET/Compatibility/Lock.cs @@ -0,0 +1,8 @@ +#if NET8_0 + +// ReSharper disable once CheckNamespace +namespace ScreenCapture.NET.Compatibility.Net8; + +public sealed class Lock; + +#endif \ No newline at end of file diff --git a/ScreenCapture.NET/Extensions/BlackBarDetection.cs b/ScreenCapture.NET/Extensions/BlackBarDetection.cs index 99848d8..00aa522 100644 --- a/ScreenCapture.NET/Extensions/BlackBarDetection.cs +++ b/ScreenCapture.NET/Extensions/BlackBarDetection.cs @@ -119,7 +119,6 @@ public static class BlackBarDetection #endregion - #region Image /// diff --git a/ScreenCapture.NET/Generic/AbstractScreenCapture.cs b/ScreenCapture.NET/Generic/AbstractScreenCapture.cs index baf819b..78dcd94 100644 --- a/ScreenCapture.NET/Generic/AbstractScreenCapture.cs +++ b/ScreenCapture.NET/Generic/AbstractScreenCapture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using HPPH; namespace ScreenCapture.NET; @@ -13,10 +14,12 @@ public abstract class AbstractScreenCapture : IScreenCapture private bool _isDisposed; + protected readonly Lock CaptureZonesLock = new(); + /// /// Gets a list of registered on this ScreenCapture. /// - protected HashSet> CaptureZones { get; } = new(); + protected HashSet> CaptureZones { get; } = []; /// public Display Display { get; } @@ -63,7 +66,7 @@ public abstract class AbstractScreenCapture : IScreenCapture result = false; } - lock (CaptureZones) + lock (CaptureZonesLock) foreach (CaptureZone captureZone in CaptureZones.Where(x => x.AutoUpdate || x.IsUpdateRequested)) { try @@ -113,7 +116,7 @@ public abstract class AbstractScreenCapture : IScreenCapture { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); - lock (CaptureZones) + lock (CaptureZonesLock) { ValidateCaptureZoneAndThrow(x, y, width, height, downscaleLevel); @@ -195,7 +198,7 @@ public abstract class AbstractScreenCapture : IScreenCapture { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); - lock (CaptureZones) + lock (CaptureZonesLock) { if (!CaptureZones.Contains(captureZone)) throw new ArgumentException("The capture zone is not registered to this ScreenCapture", nameof(captureZone)); diff --git a/ScreenCapture.NET/Model/CaptureZone.cs b/ScreenCapture.NET/Model/CaptureZone.cs index 93637f5..c4caa16 100644 --- a/ScreenCapture.NET/Model/CaptureZone.cs +++ b/ScreenCapture.NET/Model/CaptureZone.cs @@ -16,7 +16,7 @@ public sealed class CaptureZone : ICaptureZone { #region Properties & Fields - private readonly object _lock = new(); + private readonly Lock _lock = new(); /// public Display Display { get; } @@ -150,7 +150,11 @@ public sealed class CaptureZone : ICaptureZone /// public IDisposable Lock() { +#if NET8_0 Monitor.Enter(_lock); +#else + _lock.Enter(); +#endif return new UnlockDisposable(_lock); } @@ -187,14 +191,14 @@ public sealed class CaptureZone : ICaptureZone #region Properties & Fields private bool _disposed = false; - private readonly object _lock; + private readonly Lock _lock; #endregion #region Constructors // ReSharper disable once ConvertToPrimaryConstructor - public UnlockDisposable(object @lock) => this._lock = @lock; + public UnlockDisposable(Lock @lock) => this._lock = @lock; ~UnlockDisposable() => Dispose(); #endregion @@ -206,7 +210,12 @@ public sealed class CaptureZone : ICaptureZone { ObjectDisposedException.ThrowIf(_disposed, this); +#if NET8_0 Monitor.Exit(_lock); +#else + _lock.Exit(); +#endif + _disposed = true; GC.SuppressFinalize(this); diff --git a/ScreenCapture.NET/ScreenCapture.NET.csproj b/ScreenCapture.NET/ScreenCapture.NET.csproj index fd9a0b3..516413d 100644 --- a/ScreenCapture.NET/ScreenCapture.NET.csproj +++ b/ScreenCapture.NET/ScreenCapture.NET.csproj @@ -1,6 +1,6 @@  - net8.0 + net9.0;net8.0 latest enable true @@ -53,6 +53,10 @@ $(DefineConstants);RELEASE + + + + True diff --git a/Tests/ScreenCapture.NET.Tests/ScreenCapture.NET.Tests.csproj b/Tests/ScreenCapture.NET.Tests/ScreenCapture.NET.Tests.csproj index 1327462..141086c 100644 --- a/Tests/ScreenCapture.NET.Tests/ScreenCapture.NET.Tests.csproj +++ b/Tests/ScreenCapture.NET.Tests/ScreenCapture.NET.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable false