-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Issue 14204 fix data grid view excessive cpu+memory usage #14224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Issue 14204 fix data grid view excessive cpu+memory usage #14224
Conversation
|
This fix has been tested and verified. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #14224 +/- ##
===================================================
+ Coverage 77.15242% 77.18534% +0.03291%
===================================================
Files 3279 3279
Lines 645333 645151 -182
Branches 47720 47732 +12
===================================================
+ Hits 497890 497962 +72
+ Misses 143757 143509 -248
+ Partials 3686 3680 -6
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a critical performance issue in DataGridView where applications with large datasets (700k+ rows) experience severe UI freezes when closing forms or removing columns. The root cause was that iterating over the DataGridViewRowCollection using foreach would unshare (clone) each shared row, causing massive memory allocation and CPU usage.
Changes:
- Replaced inefficient foreach loops that trigger row cloning with HashSet-based deduplication using direct SharedList access
- Added a helper method
ReleaseRowUiaProviders()to centralize row UIA provider cleanup logic - Applied the same optimization pattern to both form disposal and column removal scenarios
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| DataGridView.Methods.cs | Added ReleaseRowUiaProviders() helper and modified ReleaseUiaProvider() to use HashSet deduplication when iterating over rows, preventing costly row cloning |
| DataGridViewColumnCollection.cs | Modified RemoveAtInternal() to use HashSet deduplication when releasing UIA providers for cells in the removed column |
src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs
Show resolved
Hide resolved
src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs
Outdated
Show resolved
Hide resolved
...tem.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewColumnCollection.cs
Outdated
Show resolved
Hide resolved
…e-based row navigation and row-header fallback to preserve lazy AO creation
Please fix the failure test cases firstly.
Fixes #14204
Root Cause
The foreach loop over DataGridViewRowCollection uses an enumerator that calls this[index], which unshares (clones) each shared row. For 700k rows, this causes massive memory allocation and CPU usage.
Proposed changes
DataGridViewRowAccessibleObject.Navigate(AccessibleNavigation.Previous/Up)has been changed from navigating through accessibility child indices (AccessibilityObject.GetChild(...)) to direct navigation based on the DataGridView row API:Rows.GetPreviousRow(currentIndex, DataGridViewElementStates.Visible)to get the previous row index;Rows[index].AccessibilityObject, ensuring that the target row's AccessibilityObject is created only when needed (Lazy).Customer Impact
Regression?
Risk
Screenshots
Before
Closing a form with 700k rows causes 5-10+ seconds of UI freeze and high memory spike due to row cloning.
After
Form closes near-instantly with minimal memory overhead.
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow