Changes in System.Windows.Forms.Screen in .NET 4.7 have caused the DataGridView to trigger an induced GC on every mouse wheel event. Specifically, this stack trace ends in a call to GC.Collect:
System.Internal.HandleCollector+HandleType.Add(IntPtr)
System.Windows.Forms.Internal.DeviceContext.FromCompatibleDC(IntPtr)
System.Windows.Forms.Internal.WindowsGraphics.CreateMeasurementWindowsGraphics(IntPtr)
System.Windows.Forms.Screen..ctor(IntPtr, IntPtr)
System.Windows.Forms.Screen.FromHandleInternal(IntPtr)
System.Windows.Forms.DataGridView.FlushDisplayedChanged
System.Windows.Forms.DataGridView.ScrollRowsByCount(Int32, ScrollEventType)
System.Windows.Forms.DataGridView.OnMouseWheel(MouseEventArgs)
System.Windows.Forms.Control.WmMouseWheel(Message&)
System.Windows.Forms.Control.WndProc(Message&)
System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
This makes scrolling a DataGridView with the mouse wheel effectively unusable -- the UI thread is blocked for 1-3 seconds every time you move the wheel.
Before using the mouse wheel, this is the ".NET CLR Memory" display from Process Explorer:

After scrolling the DataGridView with the mouse wheel several times:

Probably worth mentioning that this isn't the only path to triggering an induced GC in 4.7; it's just the best example I've found. Showing a ContextMenuStrip can also trigger an induced GC, delaying the context menu from appearing on the screen for more than a second. Haven't tracked down the exact call sequence for this one, but I suspect it's essentially the same -- constructing a Screen object to measure for placement.
Came across this problem as well through another situation - merging of the toolbar for MDI child forms.
Attached is a DotTrace stack tree with information. Note that all significant percentages were a result of this same call to System.Internal.HandleCollector+HandleType.Add(IntPtr) so the total result is that 96% of the time to switch activation of MDI forms is in that call (the CG.Collect and Thread.Sleep inside it, specifically).
This is causing severe performance problems in our application when run in .Net 4.7.

Thank you for reporting this issue. We are fixing this bug in the next release of .Net Framework (4.7.1) as well as working on a "hot fix" for .Net 4.7.
Thanks! That is very good to know. It will make our users very happy as most of them are avoiding the Windows 10 Creator's Update as well as the normal .Net 4.7 updates because of this issue.
@Tanya-Solyanik Thanks! We've seen this from various code paths leading to the Screen.ctor, I assume they will all be fixed (i.e. not just the DataGridView described here)? Any idea when the hot fix will be available?
@apwr Screen class constructor is fixed, thus all paths that invoke it should be taken care of. We are working on a hot fix, but don't have release dates yet.
For those who also suffer from this problem (for us, creation a complex modal form went up from a few seconds to 30 seconds), here is a dirty workaround: before creating the form, suspend the HandleCollector:
Type typeHandleCollector = Type.GetType("System.Internal.HandleCollector,System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", true);
MethodInfo methodInfoSuspendHandleCollector = typeHandleCollector.GetMethod("SuspendCollect", BindingFlags.Static | BindingFlags.NonPublic);
methodInfoSuspendHandleCollector.Invoke(null, null);
Don't forget to call "HandleCollector.ResumeCollect" after creating the form.
MethodInfo methodInfoResumeHandleCollector = typeHandleCollector.GetMethod("ResumeCollect", BindingFlags.Static | BindingFlags.NonPublic);
methodInfoResumeHandleCollector .Invoke(null, null);
Hope this has no side effects...
Official patches for Windows 10 creators Update that take care of the bug in Screen constructor are available here:
http://www.catalog.update.microsoft.com/Search.aspx?q=KB4032188
@Tanya-Solyanik I confirm it fixes the performance issues on Windows 10.
Is the fix for 4.7 on Windows 7 already out as well ?
Thanks !
@gluck - thank you for verification. Update for Windows 7 and all other OSs will be available in the end of August.
@Tanya-Solyanik Thanks for keeping us in-the-loop. This is very nice to know.
Pre-release version of .Net 4.7.1 that contains this fix and is compatible with Windows 7 is available here:
https://github.com/Microsoft/dotnet-framework-early-access/
Hello !
I think I've the same issue using the 4.6.2 July 2017 Preview update (KB4024848). I've a lot of performance issue and profiling call stack is pointing the same problem.
Do you know if this will be fixed as well before the next official 4.6.2 ?
Regards,
Florian
@reeflog
Hi Florian, you are probably facing a different issue.
Please verify what version of .Net framework you are running on, to get the version look up the reg key as described here:
https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
This particular bug had been introduced in 4.7 and is not present in the lower versions.
Thank you, Tanya
@Tanya-Solyanik I can confirm the August Cumulative Update for Windows 1703 fixes this issue.
However, are you absolutely sure the bug hasn't been backported to 4.6.2? We had blocked .NET 4.7 and the Creators Update because of this bug, but I have users now reporting severe performance problems on .NET 4.6.2. The symptoms look exactly the same: induced GC while scrolling, opening context menus, etc. The problems started after last week's Windows patches, and the affected machines have Windows 1607 and .NET 394802.
Looking further (and for some unknow reason), the July Preview update for 4.6.2 seems to actually install 4.7. At least, the assembly version show 4.7 after the update.
I don't know in which way to consider it but either it was a package issue which will be most probably fixed. Or the next 4.6.2 is 4.7... and it's fixed as well.
Thank you.
Version of the .Net Framework is stored in:
HKEY_LOCAL_MACHINESOFTWAREMicrosoftNET Framework SetupNDP
registry key, and is not modified by the updates.
Servicing updates install newer versions of the updated dlls only. Your file version after the update should match file version listed in the KB description article:
https://support.microsoft.com/en-us/help/4033989
In this case KB4033989 fixes the GDI+ leak that was indeed backported to 4.6.2 in the July update and is now fixed in the August update.
Thank you, Tanya
I can confirm that I also have the same issue on WIndows 10 1607 version.
@Tanya-Solyanik do you know if there will be a KB that include the fix for Windows 1607 versions?
Thank you.
@heeko, do you have the latest updates? KB4034661 should install System.Windows.Forms.dll v 4.7.2106 on your machine. What version do you have?
https://support.microsoft.com/en-us/help/4034661
http://www.catalog.update.microsoft.com/Search.aspx?q=KB4034661
@Tanya-Solyanik I currently have KB4035631, which seems to be 'younger' than the KB4034661 that you mentioned (base on catalog.update modification date). I will try to get this KB.
Thanks a lot for your help.
Most helpful comment
Official patches for Windows 10 creators Update that take care of the bug in Screen constructor are available here:
http://www.catalog.update.microsoft.com/Search.aspx?q=KB4032188