一、问题描述
在一个Form里添加一个ContextMenuStrip。如果在运行的时候反复打开然后关闭该Form,我们发现程序中出现内存泄露。
二、问题重现
1. 在Visual Studio中创建一个Winforms项目;
2. 在项目中添加一个Form(Form2);
3. 在Form2中添加一个ContextMenuStrip;
4. 为Form2添加一个MouseClick事件响应器(Event Handler);
5. 为Form2_MouseClick添加如下代码:
private void Form2_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
contextMenuStrip1.Show(this, new Point(10, 10));
}
}
6. 在Form1中添加一个Button;
7. 在Form1中为button1添加Click事件响应器;
8. 为button1_C lick添加如下代码:
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.ShowDialog();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
9. 编译运行;
10. 在Form1上点击button1,弹出Form2;
11. 在Form2上单击右键,弹出菜单,在关闭Form2;
12. 在WinDbg中Attach该程序,用如下命令统计UserPreferenceChangedEventHandler的数量:
!dumpheap -stat -type Microsoft.Win32.UserPreferenceChangedEventHandler
13. 重复第11、12步,我们会注意到没多重复一次,UserPreferenceChangedEventHandler会多一个实例。内存泄露发生了。
三、问题分析
当Winforms为一个控件(Control)创建句柄的时候,会为UserPreferenceChanged注册一个事件响应器。当我们销毁该控件的句柄时,我们会删除这个事件响应器。通常一个控件的句柄在两种情况下会被销毁:一是当该控件收到WM_C LOSE消息时,二是当控件被Dispose的时候。
通常当我们关掉一个Form的时候,Form本身以及它的子控件都能收到WM_CLOSE消息,因此控件的句柄都会被销毁,同时UserPreferenceChanged的事件响应器也会被删除。但当一个ContextMenuStrip为不可见的时候,是收不到WM_CLOSE消息的,因此它的UserPreferenceChanged 事件响应器没被删除,从而导致内存泄露。
为了能销毁它的句柄并删除对应的UserPreferenceChanged事件响应器,我们应该调用它的Dispose函数。
四、解决方案
在上面的例子中,我们需要如下两步来Dispose一个ContextMenuStrip:
1. 把Form2.Dispose调用ContextMenuStripMenu.Dispose
protected override void Dispose(bool disposing)
{
if (disposing)
{
if(components != null)
components.Dispose();
contextMenuStrip1.Dispose();
}
base.Dispose(disposing);
}
2. 当关闭Form2的时候,调用Form2.Dispose。我们可以通过using关键字来自动Dispose Form2:
private void button1_Click(object sender, EventArgs e)
{
using (Form2 form = new Form2())
form.ShowDialog();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
分享到:
相关推荐
验证.WinForms 扩展以允许验证WinForms UI。 可通过获得支持。 内容 NuGet包 用法 在程序集加载时一次启用VerifyXaml: VerifyWinForms . Enable (); | 形成 可视元素(窗体/控件等)可以按以下方式进行验证: ...
在C#的WinForms中嵌入WPF显示3D图形并导出为STL格式: 1.创建项目: 在Visual Studio中创建一个新的WinForms项目。 2.添加WPF支持: 向解决方案中添加一个新的WPF用户控件库项目。 3.WPF控件嵌入WinForms: 使用...
webview-winforms 由和提供支持的 Winforms 中的 Webview
Windows窗体(WinForms)是用于构建Windows桌面应用程序的UI框架。 它是Windows用户界面库(例如User32和GDI +)上的.NET包装。 它还提供Windows窗体特有的控件和其他功能。 Windows窗体还提供了基于Visual Studio...
VS13.WinForms概述使用Visual Studio 2013进行WinForms开发的开发组件和设计机制。 项目VS13.Reminders.Lib,VS13.Reminders.Win为WinForms应用程序提供Outlook样式的项目提醒。 通知区域中的VS13.TrayIcon.Lib,...
在这个“Register-WinForms”项目中,开发者利用C#的语法和Windows Forms库来设计和实现用户界面,包括各种控件如文本框、按钮、列表视图等,用于输入和展示图书数据。 系统的核心功能可能包括以下几个方面: 1. *...
Unity Windows表单 在“ UnityEngine.GUI”类的顶部构建的Unity3d的Windows窗体端口(包括System.Drawing)。 支持的控件 按钮; 复选框; 组合框; DateTimePicker; FontDialog; 形成; GroupBox;...
可以用作独立应用程序,也可以轻松集成到您的项目中。 注意:没有许可证的应用程序将在试用模式下运行,请购买或请求。 支持的文件格式 家庭 格式 便携式文件格式 PDF 微软Word DOC , DOCM , DOCX , DOT , ...
CefSharp是Chromium Embedded Framework(CEF)的一个.NET封装,使得C#程序员可以轻松地在Winforms应用中嵌入一个功能完备的浏览器组件。 首先,要理解CefSharp的工作原理。CefSharp是通过CEF来实现的,CEF是一个...
“mvp-winforms”是一个项目,它关注的是如何在Windows窗体应用程序中应用Model-View-Presenter(MVP)设计模式,并结合Entity Framework(EF)的Code First策略来构建清晰的系统架构。 **MVP模式详解:** Model-...
Microsoft 帐户 Windows 窗体该库提供了一种从 Windows 窗体应用程序生成 Microsoft 帐户访问和刷新令牌的简单方法。... 您的应用程序需要在 API 设置页面上配置为移动或桌面客户端应用程序,此库才能工作。...
CNPJ咨询-API ReceitaWS :office_building: Projeto副顾问CNPJ实用程序Windows窗体+ API ReceitaWS + SQL Server 基础做项目: : API的实用程序 ...观察API: 否,不存在3个请求,并保留所有权利;...
在Windows Forms(WinForms)开发中,Timer控件、ListView控件和TreeView控件是非常重要的组件,它们在创建用户界面和实现特定功能时起到关键作用。以下是对这些控件的详细说明: 1. **Timer控件** Timer控件是...
这个库提供了丰富的功能,允许开发者在他们的WinForms应用程序中轻松集成各种类型的图表和图形界面,如流程图、组织结构图、网络拓扑图、时间线图等。"WinFormsTrial_2019R1" 指的是这个库的一个2019年R1版本的试用...
9. **资源管理**:游戏可能包含图片、音频等资源,开发者需要妥善管理这些资源,确保它们能在程序中正确加载和释放,避免内存泄漏。 10. **版本控制与部署**:项目完成后,开发者需要打包应用程序,生成.exe可执行...
在 WinFormsUI 中,主要的核心类是 DockPanel,它提供了停靠窗口的功能。DockPanel 可以容纳多个子控件,这些控件可以停靠在面板的顶部、底部、左侧、右侧,也可以填充整个面板。这种停靠能力使得用户可以根据需要...
标题 "Microsoft.ReportViewer.WinForms.dll" 是微软开发的一个控件,用于在Windows Forms应用程序中嵌入报表查看器功能。这个DLL文件是.NET Framework的一部分,主要用于显示和交互基于Microsoft SQL Server ...
WinForms是.NET Framework中的一个用户界面框架,而C#是微软开发的面向对象的编程语言,它们共同构建了强大的Windows桌面应用程序。 首先,`WebBrowser`控件是.NET Framework提供的一种组件,允许开发者在应用程序...
标签中的“ModernUI”通常指的是Modern UI for .NET,这是一个开源项目,它允许开发人员在WinForms应用中使用类似Windows 8的Modern(或称Metro)界面风格。另外,“Winforms”和“stiffcld_winform”可能是项目作者...
在C#编程环境中,WinForms是一个用于构建桌面应用程序的强大框架。在WinForms应用中,计时器(Timer)是一个常用组件,它允许开发者在特定时间间隔执行某些操作。本篇文章将深入探讨C#中的计时器及其在WinForms中的...