Fix flaky UserPreferenceTests.SignalsUserPreferenceEventsAsynchronously under JIT stress#125676
Fix flaky UserPreferenceTests.SignalsUserPreferenceEventsAsynchronously under JIT stress#125676
Conversation
…ious OS events Co-authored-by: danmoseley <6385855+danmoseley@users.noreply.github.com>
|
@copilot did you verify pass against both .NET Framework and .NET Core? Did you loop a bunch of times? Ideally enough loops to repro without the fix, then same loops to verify fix |
There was a problem hiding this comment.
Pull request overview
Updates SystemEvents user-preference async signaling tests to only capture and signal when the observed event category matches the test’s expected category, reducing false failures when a single Windows message results in multiple preference categories being raised.
Changes:
- Filter
UserPreferenceChanginghandler to only record/set whene.Category == expectedCategory. - Filter
UserPreferenceChangedhandler similarly, and only capture the correspondingchangingArgsfor the same expected category.
The sandbox environment I'm running in is Linux — What I can confirm:
Why the race is real and the fix is correct: The race happens when the OS broadcasts a real
Without the fix, the first With the fix, the handler silently ignores any event whose category doesn't match To repro on Windows: The race can be made deterministic by adding a |
|
Tagging subscribers to this area: @dotnet/area-microsoft-win32 |
Description
SignalsUserPreferenceEventsAsynchronouslywas flaky under jitstress2-jitstressregs because the OS can broadcast spuriousWM_SETTINGCHANGEmessages (withwParam=0→ categoryGeneral) into the SystemEvents window's queue between handler registration and when the test's own reflected message is processed. JIT stress slows execution, widening this race window.The async path works like this:
WM_SETTINGCHANGE→PostMessageW(WM_REFLECT + WM_SETTINGCHANGE)(async). Any real OS broadcast during that gap fires the test'schangingHandlerwith the wrong category before the test's own message is processed.Fix
Guard both
changingHandlerandchangedHandlerto only signal and capture args whene.Category == expectedCategory, ignoring spurious OS-generated events:The
SignalsUserPreferenceEventsSynchronouslycounterpart is unaffected — it sendsWM_REFLECT + WM_SETTINGCHANGEdirectly viaSendMessageW, so handlers fire inline with no async gap.Testing
Microsoft.Win32.SystemEventstests target onlynet11.0-windowsandnet481and cannot be run in a Linux sandbox. The jitstress pipeline where the original failure was observed serves as the CI validation for this fix. The race can be made deterministic locally on Windows by adding aThread.Sleepbetween handler registration andSendMessageto give OS messages a window to arrive.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.