【问题标题】:ToolStrip memory leakToolStrip 内存泄漏
【发布时间】:2010-12-24 08:34:47
【问题描述】:

我遇到了 SWF-ToolStrip 的内存泄漏问题。 据此http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115600# 已解决。但是这里好像没有。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 它在哪个版本的 .NET 框架中得到解决?你用的是那个版本吗?
  • 我正在使用最新的 .Net 框架。 3.5.但我们决定移除工具条并使用其他控件实现该功能以解决内存问题。

标签: c# winforms memory memory-leaks toolstrip


【解决方案1】:

这个问题似乎在 .NET 3.5 SP1 和 .NET 4.0 中仍然存在。

要重现该问题,您必须创建一个 ToolStrip,其中包含的项目多于它可以显示的数量,这会导致它创建一个溢出按钮。 该问题仅在您实际单击溢出按钮时出现。单击它会创建一个 ToolStripOverflow 对象,该对象订阅 Microsoft.Win32.UserPreferenceChangedEventHandler 事件。 ToolStrip 不会释放 ToolStripOverflow 对象,这会导致事件处理程序未被删除并导致泄漏。

这给我们在创建带有 ToolStrips 的表单的大型应用程序中带来了巨大的问题。

一种解决方法是更改​​承载 ToolStrip 的表单或控件的 Dispose 方法,如下所示:

protected override void Dispose(bool disposing)
{

    if (disposing)
    {
        var overflow = toolStrip1.OverflowButton.DropDown as ToolStripOverflow;
        if (overflow != null)
            overflow.Dispose();
    }


    if (disposing && (components != null))
    {
        components.Dispose();
    }
    base.Dispose(disposing);
}

这为我们解决了问题

【讨论】:

    【解决方案2】:

    这是一个非常持久的抱怨。泄漏源是 ToolStrip 为 SystemEvents.UserPreferenceChanged 事件安装事件处理程序。这样它就可以响应用户更改主题或配色方案并重新绘制自己。这是一个静态事件,忘记注销事件处理程序将永久泄漏 ToolStrip 实例。

    该错误已在 .NET 3.5 SP1 中得到修复。 ToolStrip.Dispose() 方法取消注册事件处理程序。如果这是您正在运行的版本,请确保 Dispose() 方法确实运行。一个常见的错误是使用 Controls.Remove() 从表单中删除一个控件,然后忘记对删除的控件调用 Dispose()。

    【讨论】:

      【解决方案3】:

      Private Sub frmBase_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) 处理 Me.FormClosed

          ' .NET BUG WORKAROUND
          ' MANUALLY DISPOSE OF ToolStip, MenuStrip and StatusStrip to release memory being held
          Dim aNames As New ArrayList
          Dim count As Integer = 0
      
          For Each oItem As ToolStripItem In Me.MenuStrip1.Items
              aNames.Add(oItem.Name)
          Next
      
          For i As Integer = 0 To aNames.Count - 1
              For Each oItem As ToolStripItem In Me.MenuStrip1.Items
                  If oItem.Name = aNames(i) Then
                      oItem.Dispose()
                      Exit For
                  End If
              Next
          Next
      
          count = 0
          aNames.Clear()
          For Each oItem As ToolStripItem In Me.ToolStrip1.Items
              aNames.Add(oItem.Name)
          Next
      
          For i As Integer = 0 To aNames.Count - 1
              For Each oItem As ToolStripItem In Me.ToolStrip1.Items
                  If oItem.Name = aNames(i) Then
                      oItem.Dispose()
                      Exit For
                  End If
              Next
          Next
      
          count = 0
          aNames.Clear()
          For Each oItem As ToolStripItem In Me.StatusStrip1.Items
              aNames.Add(oItem.Name)
          Next
      
          For i As Integer = 0 To aNames.Count - 1
              For Each oItem As ToolStripItem In Me.StatusStrip1.Items
                  If oItem.Name = aNames(i) Then
                      oItem.Dispose()
                      Exit For
                  End If
              Next
          Next
      
          Me.MenuStrip1.Dispose()
          Me.ToolStrip1.Dispose()
          Me.StatusStrip1.Dispose()
      
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-08
        • 2013-01-20
        • 2011-10-31
        • 2019-08-10
        • 2013-06-24
        • 2011-03-22
        相关资源
        最近更新 更多