diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs
index e76554e..2d1f2eb 100644
--- a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs
+++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs
@@ -12,6 +12,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
{
#region Properties & Fields
+ private bool _isDisposed = false;
+
private readonly double _defaultUpdateRateHardLimit;
///
@@ -60,6 +62,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
this._defaultUpdateRateHardLimit = defaultUpdateRateHardLimit;
}
+ ~AbstractRGBDeviceProvider() => Dispose(false);
+
#endregion
#region Methods
@@ -67,6 +71,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
///
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
{
+ if (_isDisposed) throw new ObjectDisposedException(GetType().FullName);
+
ThrowsExceptions = throwExceptions;
try
@@ -108,6 +114,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
/// The filtered collection of loaded devices.
protected virtual IEnumerable GetLoadedDevices(RGBDeviceType loadFilter)
{
+ if (_isDisposed) throw new ObjectDisposedException(GetType().FullName);
+
List devices = new();
foreach (IRGBDevice device in LoadDevices())
{
@@ -152,6 +160,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
/// The update trigger mapped to the specified id.
protected virtual IDeviceUpdateTrigger GetUpdateTrigger(int id = -1, double? updateRateHardLimit = null)
{
+ if (_isDisposed) throw new ObjectDisposedException(GetType().FullName);
+
if (!UpdateTriggerMapping.TryGetValue(id, out IDeviceUpdateTrigger? updaeTrigger))
UpdateTriggerMapping[id] = (updaeTrigger = CreateUpdateTrigger(id, updateRateHardLimit ?? _defaultUpdateRateHardLimit));
@@ -171,6 +181,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
///
protected virtual void Reset()
{
+ if (_isDisposed) throw new ObjectDisposedException(GetType().FullName);
+
foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggerMapping.Values)
updateTrigger.Dispose();
@@ -192,6 +204,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
/// true if the device was added successfully; otherwise false.
protected virtual bool AddDevice(IRGBDevice device)
{
+ if (_isDisposed) throw new ObjectDisposedException(GetType().FullName);
+
if (InternalDevices.Contains(device)) return false;
InternalDevices.Add(device);
@@ -207,6 +221,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
/// true if the device was removed successfully; otherwise false.
protected virtual bool RemoveDevice(IRGBDevice device)
{
+ if (_isDisposed) throw new ObjectDisposedException(GetType().FullName);
+
if (!InternalDevices.Remove(device)) return false;
try { OnDevicesChanged(DevicesChangedEventArgs.CreateDevicesRemovedArgs(device)); } catch { /* we don't want to throw due to bad event handlers */ }
@@ -241,12 +257,26 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
protected virtual void OnDevicesChanged(DevicesChangedEventArgs args) => DevicesChanged?.Invoke(this, args);
///
- public virtual void Dispose()
+ public void Dispose()
{
- Reset();
+ if (_isDisposed) return;
+
+ try
+ {
+ Dispose(true);
+ }
+ catch { /* don't throw in dispose! */ }
GC.SuppressFinalize(this);
+
+ _isDisposed = true;
}
+ ///
+ /// Disposes the object and frees all resources.
+ ///
+ /// true if explicitely called through the Dispose-Method, false if called by the destructor.
+ protected virtual void Dispose(bool disposing) => Reset();
+
#endregion
}
\ No newline at end of file
diff --git a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs
index e3b093c..1558f6d 100644
--- a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs
+++ b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs
@@ -80,15 +80,16 @@ public sealed class AsusDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
try { _sdk?.ReleaseControl(0); }
catch { /* at least we tried */ }
_devices = null;
_sdk = null;
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs
index ab16a45..be075df 100644
--- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs
+++ b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs
@@ -94,12 +94,14 @@ public sealed class CoolerMasterDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
try { _CoolerMasterSDK.Reload(); }
catch { /* Unlucky.. */ }
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs
index 87ab725..88f4509 100644
--- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs
+++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs
@@ -300,12 +300,14 @@ public sealed class CorsairDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
try { _CUESDK.CorsairDisconnect(); } catch { /* at least we tried */ }
try { _CUESDK.UnloadCUESDK(); } catch { /* at least we tried */ }
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs
index 2d85a44..0baad66 100644
--- a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs
+++ b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs
@@ -86,5 +86,13 @@ public sealed class DMXDeviceProvider : AbstractRGBDeviceProvider
return updateTrigger;
}
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ _instance = null;
+ }
+
#endregion
}
\ No newline at end of file
diff --git a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs
index f88ad50..f37e4e9 100644
--- a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs
+++ b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs
@@ -66,11 +66,13 @@ public sealed class DebugDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
_fakeDeviceDefinitions.Clear();
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
index 4ebd163..f6a8862 100644
--- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
+++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
@@ -254,9 +254,9 @@ public class LogitechDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
try { _LogitechGSDK.LogiLedRestoreLighting(); }
catch { /* at least we tried */ }
@@ -264,7 +264,7 @@ public class LogitechDeviceProvider : AbstractRGBDeviceProvider
try { _LogitechGSDK.UnloadLogitechGSDK(); }
catch { /* at least we tried */ }
- GC.SuppressFinalize(this);
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs
index fb18827..c45a2df 100644
--- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs
+++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs
@@ -98,14 +98,14 @@ public class MsiDeviceProvider : AbstractRGBDeviceProvider
private void ThrowMsiError(int errorCode, bool isCritical = false) => Throw(new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)), isCritical);
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
try { _MsiSDK.UnloadMsiSDK(); }
catch { /* at least we tried */ }
-
- GC.SuppressFinalize(this);
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs
index 837a82c..9c9555b 100644
--- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs
+++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs
@@ -67,5 +67,13 @@ public sealed class NovationDeviceProvider : AbstractRGBDeviceProvider
}
}
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ _instance = null;
+ }
+
#endregion
}
\ No newline at end of file
diff --git a/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs b/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs
index 4d19484..50647a1 100644
--- a/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs
+++ b/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs
@@ -107,22 +107,22 @@ public sealed class OpenRGBDeviceProvider : AbstractRGBDeviceProvider
continue;
}
- if (device.Zones.Length == 0)
+ if (device.Zones.Length == 0)
continue;
- if (device.Zones.All(z => z.LedCount == 0))
+ if (device.Zones.All(z => z.LedCount == 0))
continue;
OpenRGBUpdateQueue updateQueue = new(GetUpdateTrigger(), i, openRgb, device);
-
+
bool anyZoneHasSegments = device.Zones.Any(z => z.Segments.Length > 0);
- bool splitDeviceByZones = anyZoneHasSegments || PerZoneDeviceFlag.HasFlag(Helper.GetRgbNetDeviceType(device.Type));
+ bool splitDeviceByZones = anyZoneHasSegments || PerZoneDeviceFlag.HasFlag(Helper.GetRgbNetDeviceType(device.Type));
if (!splitDeviceByZones)
{
yield return new OpenRGBGenericDevice(new OpenRGBDeviceInfo(device), updateQueue);
continue;
}
-
+
int totalLedCount = 0;
foreach (Zone zone in device.Zones)
@@ -149,9 +149,9 @@ public sealed class OpenRGBDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
foreach (OpenRgbClient client in _clients)
{
@@ -161,6 +161,8 @@ public sealed class OpenRGBDeviceProvider : AbstractRGBDeviceProvider
_clients.Clear();
DeviceDefinitions.Clear();
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs b/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs
index f18116f..debdc39 100644
--- a/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs
+++ b/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs
@@ -126,5 +126,13 @@ public sealed class PicoPiDeviceProvider : AbstractRGBDeviceProvider
_sdks.Clear();
}
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ _instance = null;
+ }
+
#endregion
}
\ No newline at end of file
diff --git a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs
index 344f96e..05c18c1 100644
--- a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs
+++ b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs
@@ -342,15 +342,17 @@ public sealed class RazerDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
TryUnInit();
// DarthAffe 03.03.2020: Fails with an access-violation - verify if an unload is already triggered by uninit
//try { _RazerSDK.UnloadRazerSDK(); }
//catch { /* at least we tried */ }
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
index 61f3254..eeeff1c 100644
--- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
+++ b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
@@ -133,12 +133,14 @@ public sealed class SteelSeriesDeviceProvider : AbstractRGBDeviceProvider
protected override IDeviceUpdateTrigger CreateUpdateTrigger(int id, double updateRateHardLimit) => new DeviceUpdateTrigger(updateRateHardLimit) { HeartbeatTimer = HEARTBEAT_TIMER };
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
try { SteelSeriesSDK.Dispose(); }
catch { /* shit happens */ }
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs
index 4d2e047..43077c8 100644
--- a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs
+++ b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs
@@ -70,11 +70,13 @@ public sealed class WS281XDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
DeviceDefinitions.Clear();
+
+ _instance = null;
}
#endregion
diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs
index 484bbaf..079ffb1 100644
--- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs
+++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs
@@ -94,15 +94,17 @@ public sealed class WootingDeviceProvider : AbstractRGBDeviceProvider
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- base.Dispose();
+ base.Dispose(disposing);
lock (_WootingSDK.SdkLock)
{
try { _WootingSDK.UnloadWootingSDK(); }
catch { /* at least we tried */ }
}
+
+ _instance = null;
}
#endregion