博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DataReader 链接关闭解惑篇
阅读量:6526 次
发布时间:2019-06-24

本文共 2752 字,大约阅读时间需要 9 分钟。

看到有帖子: ,大伙对链接关闭问题看似比较迷惑,这里就给解说一下:

 

不管是啥xxDataReader,都是继承DataReader实现的,所以是有共性的,因此标题就以DataReader为题了。

 

情况一:DataReader 默认链接不关闭

 

示例代码:

static
 
void
 Main(
string
[] args)
        {
            SqlConnection con 
=
 
new
 SqlConnection(
"
server=.;database=MySpace;uid=sa;pwd=123456
"
);
            con.Open();
            SqlCommand com 
=
 
new
 SqlCommand(
"
select top 1 id from blog_user
"
,con);
            SqlDataReader sdr 
=
 com.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
            
while
 (sdr.Read())
            {
            }
            Console.WriteLine(sdr.IsClosed);
            Console.WriteLine(con.State.ToString());
            Console.ReadLine();
        }

结论是:

False

Open

 

说明:默认无论是不是加System.Data.CommandBehavior.CloseConnection,读取时数据库链接不会帮你关闭。

 

情况二:DataReader 链接已关闭

 

示例代码:[以下是原文的代码]

        
protected
 
void
 bind()
        {
            SqlConnection conn 
=
 
new
 SqlConnection(ConfigurationManager.ConnectionStrings[
"
constr
"
].ToString());
            conn.Open();
            SqlCommand cmd 
=
 
new
 SqlCommand(
"
GetAllUser
"
, conn);
            SqlDataReader sdr 
=
 cmd.ExecuteReader(CommandBehavior.CloseConnection);
            repeater1.DataSource 
=
 sdr;
            repeater1.DataBind();
            Response.Write(sdr.IsClosed.ToString() 
+
 
"
<br/>
"
);
            Response.Write(conn.State.ToString());
        }

结果是:

True

Closed

 

情况:System.Data.CommandBehavior.CloseConnection加完之后,链接给你关闭了,为啥?看下面的分析原因。

 

三:分析原因

 

1:从前面的两个示例上看,区别是什么?

答:区别就在于一个只读数据,另一个绑定了数据列表控件。

 

2:为什么绑定了数据列表控件就会自动关闭链接?

答:这就涉及到数据控件绑定机制了,这里给大伙简单介绍一下:

A:要实现数据控件列表绑定,有一个接口是需要实现的:

B:实现DataReader实现此接口的代码[基类是抽象方法,所以只能到子类SqlDataReader查看]:

public
 
override
 IEnumerator GetEnumerator()
{
    
return
 
new
 DbEnumerator(
this
, (
this
._commandBehavior 
&
 CommandBehavior.CloseConnection) 
==
 CommandBehavior.CloseConnection);
}

从这代码里,我们只看到了它把CloseConnection传进DbEnumerator里了,再进去看一下:

    
public
 DbEnumerator(IDataReader reader, 
bool
 closeReader)
    {
        
if
 (reader 
==
 
null
)
        {
            
throw
 ADP.ArgumentNull(
"
reader
"
);
        }
        
this
._reader 
=
 reader;
        
this
.closeReader 
=
 closeReader;//此行设置了标志
    }

点进去只看到构造函数,并把它赋给this.closeReader属性,因为DataReader是向前读方式,所以重点还是要看其中的一个方法MoveNext:

    
public
 
bool
 MoveNext()
    {
        
if
 (
this
._schemaInfo 
==
 
null
)
        {
            
this
.BuildSchemaInfo();
        }
        
this
._current 
=
 
null
;
        
if
 (
this
._reader.Read())//此方法被调用一次,就读一次
        {
            
object
[] values 
=
 
new
 
object
[
this
._schemaInfo.Length];
            
this
._reader.GetValues(values);
            
this
._current 
=
 
new
 DataRecordInternal(
this
._schemaInfo, values, 
this
._descriptors, 
this
._fieldNameLookup);
            
return
 
true
;//有数据时直接返回,不会执行下面的关闭链接
        }
        
if
 (
this
.closeReader)//好,能进行这里,说明上面读不到数据,简说就是数据读完了
        {
            
this
._reader.Close();//关闭链接操作。
        }
        
return
 
false
;
    }

以上代码就看我注释的说明。

 

C:为什么用DataReader绑定列表控件是耍流氓?

答:因为服务端控件列表渲染出表格的周期通常比较长,所以,只有等到你看到最后结果列表出来的时候,最后一行数据才读完。

因此链接是持续相当长的处于打开状态,所以web这种并发多的情况,狂点几下,估计就报错了,链接池用满了。

 

四:最终结论是什么?

1:在绑定列表控件时,只要数据行读取完毕,就会自动关闭链接。

2:在直接读取时,不会触发绑定相关的读取,所以不会自动关闭链接。

3:在绑定列表控件时,链接长期得不到关闭,并发一来,就挂了,因此大伙就不要耍流氓了。

 

好了,打完收工,希望对大伙有所帮助。

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2011/04/06/2006412.html

你可能感兴趣的文章
用hadoop中的libhdfs和fuse-dfs构建快速云存储
查看>>
VMTools和虚拟硬件升级
查看>>
不知道自己不知道(Unknown Unknowns)的知识决定了你的发展
查看>>
Apple Watch的非“智能手表”卖点
查看>>
fedora17升级到fedora18
查看>>
单例模式(Singleton)
查看>>
函数指针和指针函数
查看>>
认识配置设置文件(INI与XML)
查看>>
影响谷歌排名算法的因素(2) – 页面的外链数量和质量
查看>>
DZ!NT论坛 3.6.711删除用户各种错解决方案
查看>>
Python的函数参数传递:传值?引用?
查看>>
[转]分享2011年8个最新的jQuery Mobile在线教程
查看>>
android call require api level
查看>>
Mac下android环境搭建
查看>>
创建Visual Studio项目模版向导的几篇参考文章
查看>>
深入浅出SQL Server Replication第一篇:走近Replication(上)
查看>>
[TopCoder][SRM] SRM 562 DIV 2
查看>>
SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第一篇)
查看>>
获取线程结束代码(Exit Code)
查看>>
简明 Vim 练级攻略 | 酷壳 - CoolShell.cn
查看>>