Fix Control.Dispose crash when dependent UserControl fails to load due to missing assembly#13840
Conversation
…e to missing assembly
1f34fac to
bfdb352
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a NullReferenceException crash that occurs when Control.Dispose() is called on a partially constructed control that failed to load due to a missing assembly dependency. The fix adds defensive null checks to prevent accessing uninitialized properties during disposal.
- Adds null-safe property access in
Control.Dispose()method - Replaces direct
ContextMenuStripproperty access with safeProperties?.TryGetValue()pattern - Ensures disposal can complete successfully even for incompletely constructed controls
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #13840 +/- ##
===================================================
+ Coverage 77.10742% 77.14106% +0.03363%
===================================================
Files 3273 3273
Lines 644925 644925
Branches 47692 47693 +1
===================================================
+ Hits 497285 497502 +217
+ Misses 143967 143745 -222
- Partials 3673 3678 +5
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
All LGTM. I explored writing a unit test that would reproduce the difference with and without this change, but I couldn’t find a reliable way to simulate the exact scenario. This fix mainly strengthens null-safety, so I think manual verification is sufficient. The change looks low-risk to merge. |
|
looks good👍 |
KlausLoeffelmann
left a comment
There was a problem hiding this comment.
It looks good to me.
Do we have telemetry, how often this happened, or was it a customer report?
Yes, it's customer-reported, and this is the only feedback we've received so far. |
|
/backport to release/10.0 |
|
Started backporting to |
Fixes #13835
Root Cause
When a control (e.g., MainObject) references another control (ExternalObject) from a separate assembly (ExternalAsm), and that assembly is missing at runtime, the constructor of MainObject fails. However, the .NET runtime still attempts to call
Dispose()on the partially constructed control. InsideControl.Dispose, accessingContextMenuStriptriggers aNullReferenceExceptionbecausePropertiesis not initialized.Proposed changes
ContextMenuStripaccess inControl.Dispose()Properties?.TryGetValue(...)to ensure safe event unsubscriptionCustomer Impact
Control.Dispose()can safely execute even when the control was never fully constructed.Regression?
Risk
Screenshots
Before
Run the attached project net10Issue.zip using .NET 10 framework, crash with Exception thrown: 'System.NullReferenceException' in System.Windows.Forms.dll
BeforeChanges.mp4
After
App exits successfully.
AfterChanges.mp4
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow