Skip to content

fix: App Alerts 'Start Monitoring' no longer freezes the UI during baseline scan#1424

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/appalerts-startmonitoring-uithread
Jul 10, 2026
Merged

fix: App Alerts 'Start Monitoring' no longer freezes the UI during baseline scan#1424
laurentiu021 merged 1 commit into
mainfrom
fix/appalerts-startmonitoring-uithread

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

Summary

Fresh ultra-audit finding (viewmodels-A-D, P2), verified against current source.

AppAlertsViewModel.StartMonitoring was a synchronous [RelayCommand] that called AppAlertService.TakeBaseline() directly on the UI thread. TakeBaseline() walks Program Files / Program Files (x86) / LocalAppData\Programs and enumerates both HKLM Uninstall registry trees (hundreds of subkeys) — the same heavy scan the tab's own RefreshInstalledAppsAsync already deliberately offloads with Task.Run. On a machine with many installed apps or a slow disk, the window froze for the whole scan.

Fix

StartMonitoring is now an async command that runs TakeBaseline() + Start() on a background thread (Task.Run) and resumes on the UI thread to set IsMonitoring/IsBusy/MonitorStatus. The generated command name (StartMonitoringCommand) is unchanged, so the XAML binding still resolves.

Safety: FileSystemWatcher creation is thread-agnostic, and the service's NewAppDetected event is marshaled via the SynchronizationContext captured at service construction — so moving Start() off-thread is safe (verified in AppAlertService).

Regression tests

  • StartMonitoring_IsAsync_AndSetsMonitoringState — the command is now IAsyncRelayCommand and, once awaited, leaves the VM monitoring.
  • Existing RefreshInstalledApps_WhileMonitoring_KeepsBusyInSyncWithMonitoring updated to await the now-async command (was .Execute(null) fire-and-forget).

Checks

  • All 3 projects build 0 warnings / 0 errors
  • Leak scan on diff: clean

…seline scan

StartMonitoring was a synchronous [RelayCommand] that ran AppAlertService.TakeBaseline()
on the UI thread — a walk of Program Files / Program Files (x86) /
LocalAppData\Programs plus a full enumeration of both HKLM Uninstall trees (hundreds
of subkeys), the same heavy scan RefreshInstalledAppsAsync already offloads with
Task.Run. On a machine with many installed apps or a slow disk the window hung for
the whole scan.

StartMonitoring is now an async command that runs TakeBaseline() + Start() on a
background thread and resumes on the UI thread to set IsMonitoring/IsBusy/MonitorStatus.
Safe: FileSystemWatcher creation is thread-agnostic and the service's NewAppDetected
event is marshaled via the SynchronizationContext captured at construction (verified).

Fixes ultra-audit finding P2 #42.

Regression tests: StartMonitoring_IsAsync_AndSetsMonitoringState (command is now
IAsyncRelayCommand and leaves the VM monitoring after await); existing
RefreshInstalledApps_WhileMonitoring test updated to await the now-async command.
@laurentiu021 laurentiu021 merged commit 44b309f into main Jul 10, 2026
4 checks passed
@laurentiu021 laurentiu021 deleted the fix/appalerts-startmonitoring-uithread branch July 10, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant