dotnet/winforms

ToolStripMenuItem can lead to memory leaks

Open

#4,808 创建于 2021年4月18日

在 GitHub 查看
 (5 评论) (1 反应) (0 负责人)C# (922 fork)batch import
:construction: work in progressarea-controls-StripControlshelp wantedtenet-performance

仓库指标

Star
 (4,100 star)
PR 合并指标
 (平均合并 14天 22小时) (30 天内合并 56 个 PR)

描述

  • .NET Core Version: all up to latest (5.0.5)

  • Have you experienced this same bug with .NET Framework?: Yes

Problem description: ToolStripMenuItem can lead to memory leaks in some special conditions.

  • Menu with submenu.
 windowsToolStripMenuItem 
  -> listToolStripMenuItem
  • Populate and clear submenu in runtime. In fact, only cleaning is important.
private void WindowsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
    for (int i = 0; i < 4; i++)
        listToolStripMenuItem.DropDownItems.Add("MenuItem" + i);
}

private void windowsToolStripMenuItem_DropDownClosed(object sender, EventArgs e)
{
    while (listToolStripMenuItem.DropDownItems.Count > 0)
        listToolStripMenuItem.DropDownItems[listToolStripMenuItem.DropDownItems.Count - 1].Dispose();
}

In certain conditions (I think that is - open only main menu and not opening submenu listToolStripMenuItem) after closing main menu some of listToolStripMenuItem subitems will remain in memory. See video below. This happens due to _displayedItems collection still have live references to removed menu items. I think this collection ( and may be _overflowItems too ) must be checked on item removal.

https://user-images.githubusercontent.com/17767561/115139643-acf23080-a03b-11eb-9be9-c0e4c2527f38.mp4

Workaround: You can call listToolStripMenuItem.DropDown.PerformLayout(); after items removal. This lead to call of SetDisplayedItems() which will clear _displayedItems of removed elements.

Expected behavior: All removed and disposed menu elements must be eligible to GC (have no live references).

Minimal repro: WinFormsCoreTest_Grid_Menu.zip

贡献者指南