WIP - optimizing start times

This commit is contained in:
2026-05-30 15:11:32 -05:00
parent 45bf81ebfa
commit b744f70b0b
8 changed files with 795 additions and 98 deletions
@@ -3,7 +3,9 @@
// Copyright (C) LibreHardwareMonitor and Contributors.
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using LibreHardwareMonitor.Hardware;
using LibreHardwareMonitor.Hardware.Storage;
@@ -13,13 +15,21 @@ namespace LibreHardwareMonitor.Windows.WinUI.Services;
public sealed class HardwareMonitorService : IDisposable
{
private const string DeferDimmDetectionSetting = "memory.deferDimmDetection";
private const string DeferCpuInitialUpdateSetting = "cpu.deferInitialUpdate";
private const string DeferNetworkDetectionSetting = "network.deferDetection";
private const string DeferNvidiaDetectionSetting = "nvidia.deferDetection";
private const string DeferStorageDetectionSetting = "storage.deferDetection";
private readonly object _updateLock = new();
private readonly UpdateVisitor _updateVisitor = new();
private bool _isOpen;
private int _treeRebuildQueued;
public HardwareMonitorService(AppSettings settings)
{
Settings = settings;
ApplyWinUiHardwareDefaults();
Computer = new Computer(settings);
Computer.HardwareAdded += HardwareChanged;
Computer.HardwareRemoved += HardwareChanged;
@@ -181,6 +191,24 @@ public sealed class HardwareMonitorService : IDisposable
ForceDriveWakeup = Settings.GetValue("forceDriveWakeupItem", false);
}
private void ApplyWinUiHardwareDefaults()
{
if (!Settings.Contains(DeferDimmDetectionSetting))
Settings.SetValue(DeferDimmDetectionSetting, true);
if (!Settings.Contains(DeferCpuInitialUpdateSetting))
Settings.SetValue(DeferCpuInitialUpdateSetting, true);
if (!Settings.Contains(DeferNvidiaDetectionSetting))
Settings.SetValue(DeferNvidiaDetectionSetting, true);
if (!Settings.Contains(DeferStorageDetectionSetting))
Settings.SetValue(DeferStorageDetectionSetting, true);
if (!Settings.Contains(DeferNetworkDetectionSetting))
Settings.SetValue(DeferNetworkDetectionSetting, true);
}
private void SetHardwareEnabled(string settingName, bool value, Action<bool> setter)
{
setter(value);
@@ -192,6 +220,31 @@ public sealed class HardwareMonitorService : IDisposable
private void HardwareChanged(IHardware hardware)
{
if (_isOpen)
RebuildTree();
QueueTreeRebuild();
}
private void QueueTreeRebuild()
{
if (Interlocked.Exchange(ref _treeRebuildQueued, 1) == 1)
return;
_ = Task.Run(async () =>
{
try
{
await Task.Delay(100).ConfigureAwait(false);
if (_isOpen)
RebuildTree();
}
catch (Exception ex)
{
Debug.WriteLine($"Hardware tree rebuild failed: {ex}");
}
finally
{
Interlocked.Exchange(ref _treeRebuildQueued, 0);
}
});
}
}
@@ -6,11 +6,13 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using LibreHardwareMonitor.Hardware;
using LibreHardwareMonitor.Hardware.Storage;
using LibreHardwareMonitor.Windows.WinUI.Services;
using LibreHardwareMonitor.Windows.WinUI.Utilities;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Windows.UI;
@@ -73,6 +75,7 @@ public sealed class MainWindowViewModel : ViewModelBase, IDisposable
];
private readonly HardwareMonitorService _hardwareMonitor;
private readonly DispatcherQueue _dispatcherQueue;
private readonly Logger _logger;
private readonly Dictionary<string, PlotSeriesViewModel> _plotSeriesByIdentifier = new();
private readonly RemoteWebServer _remoteWebServer;
@@ -91,6 +94,7 @@ public sealed class MainWindowViewModel : ViewModelBase, IDisposable
private bool _throttleAtaUpdate;
private bool _isStarted;
private bool _isStarting;
private int _rootUpdateQueued;
private string _statusText = "";
private TemperatureUnit _temperatureUnit;
private int _updateIntervalIndex;
@@ -98,6 +102,7 @@ public sealed class MainWindowViewModel : ViewModelBase, IDisposable
public MainWindowViewModel(AppSettings settings)
{
Settings = settings;
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
_hardwareMonitor = new HardwareMonitorService(settings);
_logger = new Logger(_hardwareMonitor.Computer);
_remoteWebServer = new RemoteWebServer(
@@ -703,7 +708,31 @@ public sealed class MainWindowViewModel : ViewModelBase, IDisposable
private void HardwareMonitor_TreeRebuilt(object? sender, EventArgs e)
{
UpdateRoot();
if (_dispatcherQueue.HasThreadAccess)
{
UpdateRoot();
UpdateStatus();
return;
}
if (Interlocked.Exchange(ref _rootUpdateQueued, 1) == 1)
return;
if (!_dispatcherQueue.TryEnqueue(() =>
{
try
{
UpdateRoot();
UpdateStatus();
}
finally
{
Interlocked.Exchange(ref _rootUpdateQueued, 0);
}
}))
{
Interlocked.Exchange(ref _rootUpdateQueued, 0);
}
}
private void ApplySensorValuesTimeWindow()