Datatable释放资源问题?(高手进,没深入研究的请帮顶)

论文MVP网 2009-03-25 10:09:09
小弟写了个程序,就是一个非常非常简单的查询程序,但是多次点击查询按钮会死机,麻烦大家帮我看下,初步怀疑是DATATABLE使用后没有释放掉资源,代码如下:

private void bt_chaxun_Click(object sender, EventArgs e)
{
this.bt_chaxun.Enabled = false;
DataTable dtable = new DataTable();
dtable = new DataTable();
switch (biaozhi)
{
case "0":
dtable.Columns.Add("编码", typeof(string));
dtable.Columns.Add("名称", typeof(string));
dtable.Columns.Add("应扫", typeof(string));
dtable.Columns.Add("已扫", typeof(string));
SqlCeDataReader dr91 = SqlCeHelper.ExecuteReader("SELECT SUM(shuliang) AS Expr1 FROM jilurukudan WHERE danhao='" + danhao + "' and (wuliaodaima IN (SELECT wuliaodaima FROM jilurukudan WHERE (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "'))))");
SqlCeDataReader dr92 = SqlCeHelper.ExecuteReader("SELECT wuliaomingcheng,wuliaodaima FROM jilurukudan WHERE danhao='" + danhao + "' and (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "'))");
this.listBox1.Items.Clear();
if (dr91.Read() == true && dr92.Read() == true)
{
SqlCeDataReader dr9000 = SqlCeHelper.ExecuteReader("select shuliang from rukudan where danhao='" + danhao + "' and (wuliaodaima IN (SELECT wuliaodaima FROM jilurukudan WHERE (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "')))) ");
if (dr9000.Read() == true)
{
gv(dr92[1].ToString(), dr92[0].ToString(), dr9000[0].ToString(), dr91[0].ToString(), dtable);
dr9000.Close();
}//一部分代码其实所有的DR我都已经关闭这里不多写


private void gv(string bianma, string mingcheng, string yuanshu, string xianshu, DataTable dtable)
{


if (bianma.Length > 6)
{
bianma = bianma.Substring(bianma.Length - 6);
}
if (mingcheng.Length > 9)
{
mingcheng = mingcheng.Substring(mingcheng.Length - 9);
}
if (yuanshu.Length > 6)
{
yuanshu = yuanshu.Substring(yuanshu.Length - 6);
}
if (xianshu.Length > 6)
{
xianshu = xianshu.Substring(xianshu.Length - 6);
}
DataRow drow = dtable.NewRow();
drow["编码"] = bianma;
drow["名称"] = mingcheng;
drow["应扫"] = yuanshu;
drow["已扫"] = xianshu;
dtable.Rows.Add(drow);

}

}



代码虽然稍微有点多和乱,但是大家主要看下GV和DATATABLE在NEW的时候,是否需要手动释放资源?如果点击多次 时候会造成内存浪费? 我上网查了下 有人说DATATABLE释放的时候最好手动,难道dtable。clear();dtable.dispose(), 晕 ,主要是我不确定是不是DATATBALE引起的? 大家别看我代码细节,主要看下这么定义DATATBALE是否有问题? 是否会浪费资源? 就是点击一次chaxun_click的时候来new一个dtable是否有问题? 然后问题错在那里? 或者怎么释放?不会的帮顶下 谢谢 ,会的麻烦告诉我下
...全文
1496 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
论文MVP网 2009-03-27
  • 打赏
  • 举报
回复
我已经解决了,谢谢大家了,最后结贴前公布解决过程, 因为是dr.read()用的太多,太混乱,造成内存没有放出去,解决办法 合理写好SQL语句 减少DR.READER的数量
并合理关闭 尽量使用
try {}
catch{}
finally{dr.close()}
mawering 2009-03-27
  • 打赏
  • 举报
回复
up,学习一下!
OKILOVE 2009-03-27
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 cancerser 的回复:]
SqlCeHelper.ExecuteReader
我要看这里的代码. 其他的没有问题
[/Quote]
恩,可能问题在这里,给出代码看看
gxj760998 2009-03-27
  • 打赏
  • 举报
回复
因为是dr.read()用的太多,太混乱,造成内存没有放出去.
LZ,都没有仔细看别人给你的回复。
现在的人怎么都喜欢指望别人把代码写好了直接可以拿回去用??
你要是我的同事,我依然还是只会告诉你我写的回复。
论文MVP网 2009-03-26
  • 打赏
  • 举报
回复


select wuliaodaima,wuliaomingcheng,sum(xianshu) xianshu,sum(yuanshu) yuanshu from
(select wuliaodaima,wuliaomingcheng, sum(shuliang)as xianshu ,0 yuanshu from jilurukudan where danhao='1' group by wuliaodaima,wuliaomingcheng
union
select wuliaodaima,wuliaomingcheng,0 xianshu ,shuliang yuanshu from rukudan where danhao='1') a
group by a.wuliaodaima,a.wuliaomingcheng



大家都说我SQL写的 有问题,这次我改了 ,我改成1次可以查询出来的,但是我这个在SQL2000上测试的已经是正确的了,但是我的开发数据库是SQLCE数据库,麻烦问下上面的语句在SQLCE下面有需要改的吗? 这个语句我已经在SQL2000测试过了是正确的,求此语句在SQLCE下面的写法
tkscascor 2009-03-26
  • 打赏
  • 举报
回复
你先用个最简单的sql语句查询. 查多几次看会不会影响速度 就知道问题是出在sql 还是cs代码上了
论文MVP网 2009-03-25
  • 打赏
  • 举报
回复
我 昏倒 麻烦大家看下我描述的现象再来判断下 是什么问题?谢谢大家了,现象告诉我们真的不是SQL的问题
特别 2009-03-25
  • 打赏
  • 举报
回复
if (dr91.Read() == true && dr92.Read() == true)
{
SqlCeDataReader dr9000 = SqlCeHelper.ExecuteReader("select shuliang from rukudan where danhao='" + danhao + "' and (wuliaodaima IN (SELECT wuliaodaima FROM jilurukudan WHERE (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "')))) ");
if (dr9000.Read() == true)
{
gv(dr92[1].ToString(), dr92[0].ToString(), dr9000[0].ToString(), dr91[0].ToString(), dtable);
dr9000.Close();
}//一部分代码其实所有的DR我都已经关闭这里不多写
楼主至少应该将
dr9000.Close();
放到
}//一部分代码其实所有的DR我都已经关闭这里不多写
下面
我认为问题不在楼主贴出的代码中,SQL需要优化
coodd 2009-03-25
  • 打赏
  • 举报
回复
搞这么麻烦做什么,用SqlDataAdapter.Fill(DataTable)吧。
论文MVP网 2009-03-25
  • 打赏
  • 举报
回复
24楼说我明白! 但是现在是现象 ,明白我的意思? 我第1次执行查询 完全OK! 一点问题没有,这也就是说我的SQL执行是没问题的,如果像24楼说的有问题 ,第1次查询速度会非常非常的慢,而现在不是这样的现象,现在是第1次查询完全正常,速度也正常,但是第2次查询,速度就会变慢,而且第3次会更慢,第4次会越来越慢,这样的现象告诉我们的是很明显有资源或者部分没有释放出去,所以不是SQL语句的问题? 大家明白吗?如果是SQL语句的问题,那么第1次查询和第2次查询会是一样的,都是会非常的慢,而且查多了会造成死机,2种情况的现象有很明显区别,所以大家看下我的代码是否是有的地方用过了没有释放掉? 或者是说有的地方用完后需要关闭。谢谢
SQL语句不对,肯定被否决了,因为我特意测试了下。
cancerser 2009-03-25
  • 打赏
  • 举报
回复
SqlCeHelper.ExecuteReader
我要看这里的代码. 其他的没有问题
tkscascor 2009-03-25
  • 打赏
  • 举报
回复

不死都半条命了...
surlew 2009-03-25
  • 打赏
  • 举报
回复
像你这样的sql语句很不科学的,最好不要用in来查询
http://topic.csdn.net/u/20090325/10/b31fdf29-6e80-4b3b-bb61-bacd25fd37f9.html
上面链接你看看,看了你就应该明白了!
ViewStates 2009-03-25
  • 打赏
  • 举报
回复
我认为LZ的担心是多余的,几个DATATABLE并不会使程序挂掉,也没有必要去考虑释放资源这种问题,这些完全都可以由FRAME自行处理回收。

引起你现在挂起的问题我认为是SQL语句不当照成的,你中间的循环每一次就会去执行一次查询,这个代价太大了。
假设我有10000个循环你难道就要去数据库查询10000次?

建议你这个地方的处理方式进行更改
1.更改语句,使一次查询后就能得出结果
2.如果优化SQL语句不能达到一次出结果的话,使用DATASET代替DATAREADER,将所需要的数据全部导入DATASET,然后将逻辑处理放在DATASET上,尽可能减小与数据库的连接次数。
论文MVP网 2009-03-25
  • 打赏
  • 举报
回复
代码补充下:

private void bt_chaxun_Click(object sender, EventArgs e)
{
this.bt_chaxun.Enabled = false;
DataTable dtable = new DataTable();
dtable = new DataTable();
switch (biaozhi)
{
case "0":
dtable.Columns.Add("编码", typeof(string));
dtable.Columns.Add("名称", typeof(string));
dtable.Columns.Add("应扫", typeof(string));
dtable.Columns.Add("已扫", typeof(string));
SqlCeDataReader dr91 = SqlCeHelper.ExecuteReader("SELECT SUM(shuliang) AS Expr1 FROM jilurukudan WHERE danhao='" + danhao + "' and (wuliaodaima IN (SELECT wuliaodaima FROM jilurukudan WHERE (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "'))))");
SqlCeDataReader dr92 = SqlCeHelper.ExecuteReader("SELECT wuliaomingcheng,wuliaodaima FROM jilurukudan WHERE danhao='" + danhao + "' and (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "'))");
this.listBox1.Items.Clear();
if (dr91.Read() == true && dr92.Read() == true)
{
SqlCeDataReader dr9000 = SqlCeHelper.ExecuteReader("select shuliang from rukudan where danhao='" + danhao + "' and (wuliaodaima IN (SELECT wuliaodaima FROM jilurukudan WHERE (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "')))) ");
if (dr9000.Read() == true)
{
gv(dr92[1].ToString(), dr92[0].ToString(), dr9000[0].ToString(), dr91[0].ToString(), dtable);
dr9000.Close();

dataGrid1.DataSource = dtable;
dataGrid1.TableStyles[0].GridColumnStyles[0].Width = 47;
dataGrid1.TableStyles[0].GridColumnStyles[1].Width = 128;
dataGrid1.TableStyles[0].GridColumnStyles[2].Width = 47;
dataGrid1.TableStyles[0].GridColumnStyles[3].Width = 47;

private void gv(string bianma, string mingcheng, string yuanshu, string xianshu, DataTable dtable)
{


if (bianma.Length > 6)
{
bianma = bianma.Substring(bianma.Length - 6);
}
if (mingcheng.Length > 9)
{
mingcheng = mingcheng.Substring(mingcheng.Length - 9);
}
if (yuanshu.Length > 6)
{
yuanshu = yuanshu.Substring(yuanshu.Length - 6);
}
if (xianshu.Length > 6)
{
xianshu = xianshu.Substring(xianshu.Length - 6);
}
DataRow drow = dtable.NewRow();
drow["编码"] = bianma;
drow["名称"] = mingcheng;
drow["应扫"] = yuanshu;
drow["已扫"] = xianshu;
dtable.Rows.Add(drow);

}


我相当于把那个datatble当成个参数传到一个函数里面处理,然后处理后又做DATAGRID的DATASOURCE了,这个有问题吗? 还是写成REF?
zzxap 2009-03-25
  • 打赏
  • 举报
回复
请楼主给出表结构和想要的结果。
liang4571231 2009-03-25
  • 打赏
  • 举报
回复
除非特别必要,一般资源的释放都是由.net framework的垃圾回收系统GC自动完成的.我认为与datatable没关系
wsqjg 2009-03-25
  • 打赏
  • 举报
回复
我觉得Using 和实例化一个对象,然后dispose效果差不多,因为using会自动调用对象的close 和 dispose方法,楼主这个问题我也遇到过,我每次也是直接new一个出来。帮顶!我也等待高人回答



================================================================================
viewerwang's life
http://lelespace.com/
================================================================================
zzxap 2009-03-25
  • 打赏
  • 举报
回复
"SELECT SUM(shuliang) AS Expr1 FROM jilurukudan WHERE danhao='" + danhao + "'

and (wuliaodaima IN (SELECT wuliaodaima FROM jilurukudan

WHERE (id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "'))))"

怎么同一个表用了三个in啊?你到底想做什么?
(id IN (SELECT MAX(id) FROM jilurukudan where danhao='" + danhao + "')是获取同一个单号的最大ID


论文MVP网 2009-03-25
  • 打赏
  • 举报
回复
 
private void bt_chaxun_KeyDown(object sender, KeyEventArgs e)
{ if (e.KeyCode == Keys.F1)
{
if (bt_chaxun.Enabled ==true)
this.bt_chaxun_Click(bt_chaxun, new KeyEventArgs(Keys.Enter));
}
}

能否是btchaun_click事件写的有问题? 就是KEYDOWN来完成CLICK ,因为我的是支持触摸屏幕的
加载更多回复(26)

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧