Avoid excessive memory usage and slow TrackBar control #8060
Avoid excessive memory usage and slow TrackBar control #8060lonitra merged 30 commits intodotnet:mainfrom
TrackBar control #8060Conversation
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Show resolved
Hide resolved
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
TrackBar control
|
You probably should have rebased this instead of pulling all the changes in from main. It makes it very difficult for the reviewers if you don't. |
|
Hi @conorgee, it looks like instead of rebasing you pulled completely unrelated changes in.
|
fb63287 to
955871f
Compare
TrackBar controlTrackBar control
|
What if you set the frequency prior to the min/max values via PInvoke? Did you try that? Does it improve the memory usage? |
75085ea to
4b82810
Compare
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
8425ccd to
f47e12d
Compare
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/tests/IntegrationTests/WinformsControlsTest/TrackBars.cs
Outdated
Show resolved
Hide resolved
Correcting the lexicographical order
Feature switch if user wants to opt out of fix.
Putting `DrawTicks()` in a if statement for `SetRange()`, and removing the `TBM_SETTICFREQ` message within `DrawTicks()` .
Adding the `TBM_SETTICFREQ` message within `OnHandleCreated()` .
b6aa8ab to
16b18c9
Compare
lonitra
left a comment
There was a problem hiding this comment.
LGTM, thank you so much for all your effort 🥳
|
No problem at all, thank you for the opportunity to work on this. It has been a truly remarkable learning experience for me and everyone has been very helpful . At the beginining the issue looked alot simpler then it turned out to be but luckily with the help of @RussKie and @elachlan we could figure this one out. Hats off to the WinForms team. This has been an extraordinary experience for me, thank you. |
|
Thanks for persisting with this. |
|
@merriemcgaw my assumption is that this fix will need to be documented somewhere so that users are aware of the switch? |
This should go with other switches we are introducing/introduced. #8442 |


Allow users to set large a range of values on the trackbar without excessive memory consumption.
Fixes #329
Proposed changes
Solving the issue of Memory consumption for the trackbar for large range of values on trackbar.
Turning
TBS_AUTOTICKSoff when the the tick range is larger then the physical limitations of the trackbar by checking this with the Boolean methodShouldAutoDrawTicks(). This sets the flag_autoDrawTicksinCreateParams.The fix will be put behind a feature switch called
TrackBarModernRenderinginLocalAppContextSwitchesbecause of the significant risk - primarily due to the use ofRecreateHandle()method. If they opt out of the feature theShouldAutoDrawTicks()then it will always return true. This means that the way of rendering ticks will be reverted back to the old way e.g. usingTBS_AUTOTICKSand setting tick frequency with theTBM_SETTICFREQmessage.The method
DrawTicks()replaces the messageTBM_SETTICFREQIt gets called everywhereTBM_SETTICFREQwould have been used.It checks whether the tickstyle is None (return) or
_autoDrawTicksis true which sets the_tickFrequencyusing theTBM_SETTICFREQmessage then return .When the tick range is greater then physical limitaions of the size of the trackbar it calculates if the users set
_tickFrequencywill fit on the trackbar.If the value is greater then the physical limiations we have then we set
drawnTickFrequencytorange / maxTickCount.Using a for loop we maually draw the ticks based on the
drawnTickFrequencyset.ShouldRecreateHandle()to set therecreateHandleflag in places whereDrawTicks()gets calledDrawTicks()Is refrenced in three places first is when the user wants to change theTickFrequencyand the second place isSetRange()when max or min is changed andOnHandleCreated().recreateHandleis true thenDrawTicks()will not be called in either of the first two places it will be called inOnHandleCreated()RecreateHandle()is excuted then we excuteDrawTicks();hereCustomer Impact
Regression?
Risk
RecreateHandle()method.Screenshots
Before
After
Test methodology
Test Feature Switch
TrackBarModernRenderingset to falseTrackBarModernRenderingset to trueTest int.MinValue
Test int.MaxValue
Basic Tests
Testing for a large value range to turn off
TBS_AUTOTICKSthen setting to a small range forTBS_AUTOTICKSto be turned on , works for bothhorizontalandverticalorientation.set a trackbar width to 588px, orientation horizontal, min=-100, max=1000, tick freq=1 -> expect memory consumption to be low e.g 20mb. expect 294 ticks, autoTicks disabled ticks manually drawn
Trackbar Size tests
horizontalandverticalorientation.set a trackbar width to 1,000px, orientation horizontal, min=-1000, max=1000, tick freq=1 -> expect memory consumption to be low e.g 20mb. expect 500 ticks, autoTicks disabled

set a trackbar width to 1,000px, orientation horizontal, min=-1000, max=1000, tick freq=100 -> expect memory consumption to be low e.g 20mb. expect 20 ticks, autoTicks disabled

Tickfrequency tests
works the same for both
horizontalandverticalorientation.set a trackbar width to 588px, orientation horizontal, min=-100, max=100, tick freq=100 -> expect memory consumption to be low e.g 20mb. expect 3 ticks, autoTicks enabled
Accessibility testing
TODO
Test environment(s)
.NET 8.0.0 - alpha.1.22605.1
Microsoft Reviewers: Open in CodeFlow