TabControl与UserControl合伙吃内存
Posted on 2010-04-23 03:55 苏飞 阅读(1815) 评论(29) 编辑 收藏 所属分类: Winform交流
先说一下问题的所在吧,公司的项目最近发现越来越慢一直找不到原因,主要是在加载 的时候比较慢,如果是512的内存可能要上分钟了,以前是很快的,我打开内存管理 工具一看我的天那200MB,这也太多了,我记得刚开始只有30MB左右,这是怎么回事呢?先看看我们的系统是这样的我放个图片上来吧,
左面是一个Tree,右面是一个TabControl,单击Tree里会把一个UserControl添加到TabControl里大家一看应该就明白了
我做了一个测试,才明白,我打开我们的系统一面单击一面看内存变化,我每单击一个项目会增加内存2MB左右,开始我没有认为有什么问题,因为这基本是正常的,可是当我把打开的用户控件再次关闭再打开时发现内存还在增加,再点一下又增加,也就是说单击同一个时在增加内存
这是怎么回事呢,我看了一直Tree的单击事件才明白
大家可以看一下以下的代码
代码
//button's click Tree
private void treeView1_MouseClick(object sender, MouseEventArgs e)
{
try
{
if (e.Button == MouseButtons.Left)
{
Point ClickPoint = new Point(e.X, e.Y);
TreeNode CurrentNode = treeView1.GetNodeAt(ClickPoint);
if (CurrentNode != null)//判断你点的是不是一个节点
{
treeView1.SelectedNode = CurrentNode;//选中这个节点
}
//如果是上层节点则展开之
if (treeView1.SelectedNode.Parent == null)
{
if (treeView1.SelectedNode.IsExpanded == false)
{
treeView1.SelectedNode.Expand();
}
}
else
{
//验证权限不要删除动0不存在1存在2是查询失败
if (user.checkofficeinfoFunction(OfficeInfo.ofPara1, Convert.ToInt32(CurrentNode.ToolTipText.ToString().Trim())
, OfficeInfo.ofId) == 1)
{
//加载窗体
switch (CurrentNode.Text.Trim())
{
case "中国移动":
SystemMusic.Mobile(false);
Mobile Mobile_frm = new Mobile(OfficeInfo);
Mobile_frm.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, Mobile_frm);
break;
case "中国联通":
SystemMusic.Unicom(false);
ClientSystem.China_Unicom.Unicom Unicom_frm = new ClientSystem.China_Unicom.Unicom(OfficeInfo);
Unicom_frm.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, Unicom_frm);
break;
case "中国电信":
SystemMusic.Telecom(false);
Telecom Telecom_frm = new China_Telecom.Telecom(OfficeInfo);
Telecom_frm.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, Telecom_frm);
break;
case "全国缴费":
SystemMusic.National_Mobile_Result(false);
NationalMobile objNationalMobile = new NationalMobile();
objNationalMobile.OfficeInfo = this.OfficeInfo;
objNationalMobile.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, objNationalMobile);
break;
//在这里添加新的栏目
default:
MessageBoxForm objform = new MessageBoxForm("您没有操作此栏目的权限,如有问题请与服务商联系!!!", "提示信息", MessageBoxIcon.Information);
objform.ShowDialog();
break;
}
}
else
{
MessageBoxForm objform = new MessageBoxForm("您没有操作此栏目的权限,如有问题请与服务商联系!!!", "提示信息", MessageBoxIcon.Information);
objform.ShowDialog();
}
}
}
}
catch (Exception ex)
{
MessageBoxForm objform = new MessageBoxForm("提交超时" + ex.Message.ToString(), "提示信息");
objform.ShowDialog();
}
}
不知道 大家有没有看出来这里有什么问题,其实问题就在这些代码
Mobile Mobile_frm = new Mobile(OfficeInfo);
这是生成的一个用户控件的对象然后添加到TabControl里,当然这样是没有问题的,然而有问题的是我每次都 要创建一个新的对象出来,这样一来的话,就是我上面测试的那样只要单击一次就会创建一个新的对象,而又没有关闭之前的对象,当然会每单击一次就增加内存了,看到这里我下了一跳,怪不得最近都 有人说我们的系统慢的要死,我想不慢才怪呢?那现在怎么办呢,只要想办法解决了
我们必须在创建一个新的对象前关闭之前的对象,可是这样应该怎么做呢,我所性就不创建,或是只创建一次,那这样不就没有问题了吗?
我是这样来写的,我把所有要用到的用户控件先定义出来
代码
/// <summary>
/// 火车票
/// </summary>
private tranMain objtranMain = null;
/// <summary>
/// 短信
/// </summary>
private SmsMain objSmsMain = null;
/// <summary>
/// 联通固话
/// </summary>
private UnicomPhone objUnicomPhone = null;
/// <summary>
/// 电信固话
/// </summary>
private TelecomPhone objTelecomPhone = null;
/// <summary>
/// 全国游戏
/// </summary>
private NationalMobile objNationalMobile = null;
然后把上面的一段代码稍加改动就可以了,只要我们不是每次都 New一个新的就行
代码
//button's click Tree
private void treeView1_MouseClick(object sender, MouseEventArgs e)
{
try
{
if (e.Button == MouseButtons.Left)
{
Point ClickPoint = new Point(e.X, e.Y);
TreeNode CurrentNode = treeView1.GetNodeAt(ClickPoint);
if (CurrentNode != null)//判断你点的是不是一个节点
{
treeView1.SelectedNode = CurrentNode;//选中这个节点
}
//如果是上层节点则展开之
if (treeView1.SelectedNode.Parent == null)
{
if (treeView1.SelectedNode.IsExpanded == false)
{
treeView1.SelectedNode.Expand();
}
}
else
{
//验证权限不要删除动0不存在1存在2是查询失败
if (user.checkofficeinfoFunction(OfficeInfo.ofPara1, Convert.ToInt32(CurrentNode.ToolTipText.ToString().Trim())
, OfficeInfo.ofId) == 1)
{
//加载窗体
switch (CurrentNode.Text.Trim())
{
case "中国移动":
SystemMusic.Mobile(false);
if (Mobile_frm == null)
Mobile_frm = new Mobile(OfficeInfo);
Mobile_frm.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, Mobile_frm);
break;
case "中国联通":
SystemMusic.Unicom(false);
if (Unicom_frm == null)
Unicom_frm = new ClientSystem.China_Unicom.Unicom(OfficeInfo);
Unicom_frm.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, Unicom_frm);
break;
case "中国电信":
SystemMusic.Telecom(false);
if (Telecom_frm == null)
Telecom_frm = new China_Telecom.Telecom(OfficeInfo);
Telecom_frm.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, Telecom_frm);
break;
case "全国缴费":
SystemMusic.National_Mobile_Result(false);
if (objNationalMobile == null)
objNationalMobile = new NationalMobile();
objNationalMobile.OfficeInfo = this.OfficeInfo;
objNationalMobile.Parent_Main = this;
addTabControl(CurrentNode.Text, CurrentNode.Text, MainTabControl, objNationalMobile);
break;
//在这里添加新的栏目
default:
MessageBoxForm objform = new MessageBoxForm("您没有操作此栏目的权限,如有问题请与服务商联系!!!", "提示信息", MessageBoxIcon.Information);
objform.ShowDialog();
break;
}
}
else
{
MessageBoxForm objform = new MessageBoxForm("您没有操作此栏目的权限,如有问题请与服务商联系!!!", "提示信息", MessageBoxIcon.Information);
objform.ShowDialog();
}
}
}
}
catch (Exception ex)
{
MessageBoxForm objform = new MessageBoxForm("提交超时" + ex.Message.ToString(), "提示信息");
objform.ShowDialog();
}
}
这样我测试了一下,当然再每打开新项目是会增加内存这是没有办法 的,但是 在重复单击一个项目时就不会增加内存了,因为它会是同一个对象,如果对象为Null的时候 我才会再次创建, 而且 在每次关闭一个选项卡时我都这样处理一下,调用 一个释放空间的方法UserDispose
代码
/// <summary>
/// 释放用户控件资源
/// </summary>
private void UserDispose(string name)
{
switch (name)
{
case "中国移动":
Mobile_frm.Dispose();
Mobile_frm = null;
break;
case "中国联通":
Unicom_frm.Dispose();
Unicom_frm = null;
break;
case "中国电信":
Telecom_frm.Dispose();
Telecom_frm = null;
break;
case "联通固话":
objUnicomPhone.Dispose();
objUnicomPhone = null;
break;
case "电信固话":
objTelecomPhone.Dispose();
objTelecomPhone = null;
break;
case "全国缴费":
objNationalMobile.Dispose();
objNationalMobile = null;
break;
case "QQ币充值":
objQq.Dispose();
objQq = null;
break;
case "手机短信":
objSmsMain.Dispose();
objSmsMain = null;
break;
case "3G通充值":
objtranMain.Dispose();
objtranMain = null;
break;
case "体育彩票":
TLottery_frm.Dispose();
TLottery_frm = null;
break;
case "全国游戏":
objSNationalGame.Dispose();
objSNationalGame = null;
break;
case "火车票":
objTgFrm.Dispose();
objTgFrm = null;
break;
case "中国电力":
objPower.Dispose();
objPower = null;
break;
case "身体证查询":
objCheckIDCard.Dispose();
objCheckIDCard = null;
break;
default:
break;
}
GC.Collect();
}
不知道 这样好不好不过确定是内存占用少了很多现在基本不会过50MB,以前没有注意这块,现在给大家分享一下我的经验,也希望能给常用这两个控件并且没有注意到这个问题的朋友以帮助吧,如果我的方法有不到这处还希望大家提出建议或是解决方案我将不胜感激,对性能这块如果大家有什么经验的话也希望能分享一下,呵呵
addTabControl方法
代码
/// <summary>
/// 添加一个选项卡
/// </summary>
/// <param name="MainTabControlKey">选项卡的键值</param>
/// <param name="MainTabControlName">选项卡要显示的名称</param>
/// <param name="objTabControl">要添加到的TabControl对象</param>
/// <param name="objfrm">要被添加到选项卡的用户控件对象</param>
private void addTabControl(string MainTabControlKey, string MainTabControlName, TabControl objTabControl, UserControl objfrm)
{
try
{
if (objTabControl.Controls.Contains(objTabControl.TabPages[MainTabControlName]) == false)
{
//声明新的TabPage对象tabpage
TabPage tabpage = new TabPage();
//选项卡的名称
tabpage.Text = MainTabControlName;
tabpage.Name = MainTabControlKey;
添加tabPage标签图片
switch (tabpage.Text.ToString().Trim())
{
case "中国移动":
tabpage.ImageIndex = 1;
break;
case "中国联通":
tabpage.ImageIndex = 2;
break;
case "中国电信":
tabpage.ImageIndex = 3;
break;
case "信用卡还贷":
tabpage.ImageIndex = 4;
break;
case "生活缴费":
tabpage.ImageIndex = 5;
break;
case "游戏币充值":
tabpage.ImageIndex = 6;
break;
case "彩票卖场":
tabpage.ImageIndex = 7;
break;
case "机票订购":
tabpage.ImageIndex = 8;
break;
case "全国充值":
tabpage.ImageIndex = 9;
break;
case "联通固话":
tabpage.ImageIndex = 10;
break;
case "电信固话":
tabpage.ImageIndex = 10;
break;
case "体育彩票":
tabpage.ImageIndex = 11;
break;
case "福利彩票":
tabpage.ImageIndex = 12;
break;
case "QQ币充值":
tabpage.ImageIndex = 13;
break;
case "移动选号":
tabpage.ImageIndex = 1;
break;
case "联通选号":
tabpage.ImageIndex = 2;
break;
case "电信选号":
tabpage.ImageIndex = 3;
break;
default:
tabpage.ImageIndex = 5;
break;
}
//使得objfrm充满整个父窗体
objfrm.Dock = DockStyle.Fill;
//子窗体大小设置为选项卡大小
objfrm.Size = tabpage.Size;
//在tabpage中添加panel
tabpage.Controls.Add(objfrm);
tabpage.AutoScroll = true;
tabpage.AutoScrollMinSize = new Size(700, 500);
//Image m_Img = new Bitmap(Application.StartupPath + "\\images\\001.bmp");
//if (m_Img != null)
//{
// Point pt = tabpage.AutoScrollPosition;
// e.DrawImage(m_Img, pt.X, pt.Y, m_Img.Width, m_Img.Height);
//}
//添加tabpage
objTabControl.Controls.Add(tabpage);
//使得tabpage为选中状态
objTabControl.SelectedTab = tabpage;
}
else
{
//设为当前选中的选项
objTabControl.SelectedTab = objTabControl.TabPages[MainTabControlName];
}
}
catch (Exception ex)
{
MessageBoxForm objm = new MessageBoxForm("添加选项卡时出错,请检查是否正确连接数据" + ex.Message.ToString());
objm.ShowDialog();
}
}
TabControl与UserControl合伙吃内存相关推荐
- 解决Eclipse狂吃内存的解决方法(转)
解决Eclipse狂吃内存的解决方法(转) 参考文章: (1)解决Eclipse狂吃内存的解决方法(转) (2)https://www.cnblogs.com/doublegi/p/7230144.h ...
- 浏览器插件:一款解决谷歌浏览器吃内存神器插件,你值得试一试!
Chrome浏览器是大部分开发者必备的浏览器,它的主要有点有便于调试.启动快.无广告.但是谷歌浏览器也有自己的缺点,Chrome浏览器对系统内存的占用太大了,每打开一个页面都会占用系统内存.如果你的浏 ...
- chrome 占用大量内存直到网页崩溃_Chrome吃内存太夸张!几招解决Chrome占内存硬伤...
我们知道Chrome是非常出色的浏览器,无论从性能还是功能的角度来看,都是如此.但是Chrome在内存占用方面的表现,就很令人头疼了!常常听到有朋友抱怨,想要上网找找素材,不一会儿发现Chrome已经 ...
- 上传文件实时显示网速怎么实现_担心PC程序吃内存占网速?有了它终于放心了...
自乔帮主发布iPhone至今,智能手机已经走过了13个年头,其系统.UI.操作逻辑都已经逐步完善且相当傻瓜化. 所以总有许多人切换到PC上时,总感觉缺了那么点东西,Windows系统的生产力自然是毋庸 ...
- python吃显卡还是内存条_玩天际线吃U还是吃显卡或者还是吃内存?--天际线配置需求个人见解...
作为一个天际线的伪萌新,经常能听到天际线的朋友各种问"求各位吧友,群友,水友,基友,我电脑CPU i7XXXX, 内存 XXG,显卡 GTX10XX,能否带的动天际线?" 每当看到 ...
- SqlServer狂吃内存不释放解决办法
SqlServer狂吃内存不释放,疯狂达到20G!! 问题 SqlServer有多少内存吃多少内存,肉眼可见的速度疯狂增长且不释放! 使用DATAX做数据平采,从oracle到SqlServer,数据 ...
- 微信开发者工具吃内存,页面空白
兄弟萌,踩个坑,早上微信开发者工具提示更新就直接更了,结果吃内存不偿命,页面直接空白,尽量不更还是别更新了[流鼻血] 直接版本退回可用版本即可
- 1g内存服务器Apache怎么优化,Apache性能优化-解决吃内存的问题 | kTWO-个人博客
虽然现在已经00:22了,但是还是抑制不住内心的激动,因为解决了好几天以来一直困惑我的问题--服务器httpd服务一直在吃内存,只要有人访问,服务器的内存就会小一点,慢慢的就会被吃掉所有内存,经过几天 ...
- 性能测试:wiremock 基础使用 + wiremock/wiremock + docker + 镜像发布吃内存的问题
目录 一.单纯使用wiremock在本地测试 二.wiremock/wiremock - docker的使用 三.如何在wiremock/wiremock images 中 放入 xxx.json. ...
最新文章
- 【Java】类与对象 - 对象的组合
- [TT]-Trustonic acronyms
- 【设计模式】两大策略和六大原则
- android显示字符串,Android自定义View用切图显示字符串
- 计算机应用基础 许晞课程标准,〔计算机应用基础〕课程标准.doc
- 时分多路数字电话基带传输系统
- Makefile教程(绝对经典,所有问题看这一篇足够了)
- 联想计算机无线网络设置密码,联想(Lenovo)路由器怎么设置密码?
- win10 软路由_破费装了台LEDE软路由,测试WAN口能否跑万兆(中篇)
- 计算机信息检索技术实质上是逻辑运算,在信息检索的实际过程中,如需要扩大检索范围时,如何调整检索策略...
- 计算机没桌面,电脑桌面的计算机图标没了怎么办
- 有关Excel表格公式的方式进行前边数字排序,后边内容不变的方法。
- 浏览器打开服务器图片不显示图片,网页图片不显示的原因 世界之窗浏览器网页显示不正常...
- 「前端」尚妆 UI 组件库工程实践(weex vue)
- FrameMaker 10启动时报错(Licensing for this product has expired)的解决办法
- 粘胶活化剂市场现状及未来发展趋势
- 科研伦理与学术规范期末考试1题库
- 数字变成大写的类,把人民币转化为大写汉字
- 定时且周期性的任务研究II--ScheduledThreadPoolExecutor
- 票据背书以及票据背书的好处