播客 > 玩代码  >  c# IDataReader造成的资源泄漏  | 登录  | RSS订阅地址  | Code平台

c# IDataReader造成的资源泄漏

  在ADO(+)数据访问的时候,MS曾经在其出版的书籍中强调过(有可靠证据),尽量不要使用使用DataSet访问对象,而是使用IDataReader这个只读的向前的记录集访问,的确,这是有一定的道理的,DataSet是把数据集先置于内存中,然后告诉缓存起来,断开连接,IDataReader是直接读取的.
  在数据量较少的情况下,DataSet和IDataReader的优劣并没有非常明显的优劣,然而,当数据流量达到一定量(200条左右),这和您的计算机的硬件配置有关,IDataReader的优势就很明朗了.
  在访问数据量较多的时候,如果您热衷于使用IDataReader读取数据库,那么,以下的一个问题是很明显的,如果线路阻塞,记录异常关闭,线路突然中止,这时候就数据库服务器中闲置了一条任何程序都无法再利于的线程-资源泄漏了.曾经,可以时候Close关闭链接池的,但,难道要每次DataBind完毕了操作这个么?如果DataBind失败,而您又使用了Catch语句,那这个线路又闲置了.根据本人的经验,在WinApp的开发中,.Net所限制的线路最大的pool是21,在Web开发中,更少,4条抑或更少.
  这里介绍一种方法,使用Delegates关闭,使用委托的优势就是自动关闭,每次完毕,自动激发这个委托.

  
public class DBComponent{
    public delegate void IDataReaderHandler(IDataReader reader);
    public static void GetAuthor(string authorID,IDataReaderHandler handler){
    using(SqlConnection conn=new SqlConnection("server=.;Trusted_Connection=True;DATABASE=pubs")){
       SqlCommand command=new SqlCommand("select * from class where [id]=@ID",conn);
       command.Parameters.AddWithValue("@ID",authorID); 
       conn.Open();

       using(SqlDataReader rdr=command.ExecuteReader(CommandBehavior.CloseConnection)){
        handler(rdr);
       }
    }
    }
}


注意到handler(rdr);这是引发委托的语句.

  页面使用的时候:
public class WebForm1 : System.Web.UI.Page
{
 protected System.Web.UI.WebControls.DataGrid DataGrid1;


 private void Page_Load(object sender, System.EventArgs e){

  if(!IsPostBack)
   DataComponent.GetAuthor("172-32-1176",new DataComponent.IDataReaderHandler(BindGrid)); 
 }

 private void BindGrid(IDataReader reader)
 {
  DataGrid1.DataSource = reader;
  DataGrid1.DataBind();
 }
}

  以上文章参照这里.
  稍等.
天气:大雨,ccdot发表于2007-5-7 15:03:59,阅读了2200次,共有个7回复.

好帖,这个办法我也想到了,不过没有总结出来。
楼主写的还不错,虽然有些欠缺,但是基本把握了问题的要害。
对于这个问题的完整解决办法,我曾经和微软的专家讨论过,我们得到的答案虽然和楼主不同,但是大意差不多了。

niceidea post in 2007-5-10 20:47:33 #1  

我的blog链接,帮改成www.yeat.org,去掉最后的blog目录吧,嘿嘿。

叶子 post in 2007-5-10 22:10:32 #2  

好的,马上照办,没问题.

ccdot post in 2007-5-10 22:36:32 #3  

To NiceIdea:对了,你们那次的谈话记录我前天还是在微软官网看到的,刚怎么没看到..

ccdot post in 2007-5-10 22:38:05 #4  

微软的人就是喜欢扯虎皮拉大旗;无非就是想利用我的个人效应... 我去信让他们删除了。

niceidea post in 2007-5-12 11:14:23 #5  

问个问题,如果用了代理,那怎么把取出来的DataReader数据缓存起来呢???

Atlantis post in 2007-8-14 16:49:23 #6  

那就干脆用DataSet了。

ccdot post in 2007-8-14 19:49:05 #7  
  1. 想要转载我文章的人滚远远的,能想多远,就滚多远。
  2. 不要提交任何带有网址URL信息的评论.
  3. 需要更多信息?请使用站内搜索,郁闷了?听听我在听什么吧!
用户名:*验证:看不清楚请点击刷新验证码*
内容: