DataReader不能使用using的详细示例

本文介绍了DataReader不能使用using的详细示例,分享给大家,具有如下:

public static MySqlDataReader ExecuteMySqlReader(string sqlStr)
{
MySqlConnection conn = new MySqlConnection(MyConString);
MySqlCommand cmd = new MySqlCommand(sqlStr, conn);
try
{
conn.Open();
//执行CloseConnection命令时,如果关闭关联的DataReader对象,则关联的Connection对象也将关闭
//用using(conn)会报错,因为执行完命令就会关闭连接,其它代码调用DataReader对象时,连接已经关闭。
MySqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}
catch (Exception exp)
{
throw new Exception(exp.Message);
}
}

PS:MySqlDataReader在Using中使用

结论:当DataReader放在Using方法中时,会自动释放资源,如果中途出现了异常处理,也同样会释放掉占用的资源。
测试过程:这里由于没有将全部分过程记录下来,只是对结果大体的说明一下,有兴趣的童鞋可以自己测试。

首先正常的处理流程:

MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters)
while (dr.Read())
{
keyWords.Add(dr["KeyWord"].ToString());
}
dr.Close()

这样处理貌似是没问题,不过在测试中,如果“keyWords.Add(dr["KeyWord"].ToString());”出现了异常,此时,程序会调到异常处理的模块,这样,就造成了下边的close方法不会被执行到,从而造成了数据库连接数的不断累加,当达到最大值时,问题就显露出来了。

下边第一种处理方式采用异常处理:

MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters);
try{
while (dr.Read())
{
keyWords.Add(dr["KeyWord"].ToString());
}
}
catch(){
}
finnally{
dr.Close();
}

毫无疑问,这个方法很容易想到。

第二种处理方式,这里打算使用using方法进行处理。但是根据理论知识,认为这个是可以的。但是真实的程序运行环境,确实有时不能以理论知识来指导。现在程序在这,有一个很合适的测试环境,为什么不自己测试下呢?于是就出现了一下的过程:
我是用的是MySql数据库,C#编写的程序。

首先补充一些基础知识:

1、Using定义范围:即时释放资源,在范围结束时释放资源。当在某个代码段中使用了类得实例,而希望无论什么原因,只要离开了这个代码段就自动调用这个类实例的Dispose方法释放资源。

到达using语句末尾或者中途引发了异常并且控制离开了语句块,即触发实例的Dispose方法释放资源。

然后查看MySqlDataReader的实现:

public sealed class MySqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord{...}

确实继承了IDisposable方法,理论上应该是正确的。

2、MySql查看连接数:

命令: show processlist; 如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接。
show processlist;只列出前100条,如果想全列出请使用show full processlist;

有了这两点理论知识,下边的测试就容易多了:

1、不使用using也不关闭连接:

 MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters);
 while (dr.Read())
 {
 keyWords.Add(dr["KeyWord"].ToString());
 }

测试,连接数不断增多。

2、不使用,采用关闭操作:

MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters);
while (dr.Read())
{
keyWords.Add(dr["KeyWord"].ToString());
}
dr.Close()

测试,连接数不变化。

3、不使用Using,采用关闭操作,中间执行过程制作一个异常:

MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters);
while (dr.Read())
{
keyWords.Add(dr["Keyord"].ToString());
}
dr.Close()

测试,连接数不断增多。

4、采用Using,无异常的情况:

Using(MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters))
{
while (dr.Read())
{
keyWords.Add(dr["KeyWord"].ToString());
}
}

测试,连接数未增加。

5、采用Using中间制作一个异常:

Using(MySqlDataReader dr = MySqlHelper.ExecuteReader(MySqlHelper.Conn, CommandType.Text, sqlStr, parameters))
{
while (dr.Read())
{
keyWords.Add(dr["Keyord"].ToString());
}
}

测试,连接数未增加。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • asp.net中用DataReader高效率分页

    分享一下两种方式的分页代码 1.用DataReader分页 复制代码 代码如下: /// <summary> /// PageList for DataReader /// </summary> /// <param name="connectionString"></param> /// <param name="sql"></param> /// <param name="p

  • c#中SqlHelper封装SqlDataReader的方法

    本文实例讲述了c#中SqlHelper封装SqlDataReader的方法.分享给大家供大家参考.具体如下: /// <summary> /// 执行sql语句返回一个DataReader /// 当返回DataReader的时候,注意: /// 1.Connection不能关闭 /// 2.DataReader不能关闭 /// 3.command对象执行ExecuteReader()的时候需要传递一个参数CommandBehavior.CloseConnection /// </sum

  • C#使用SQL DataReader访问数据的优点和实例

    DataReader DataReader对象提供了用顺序的,只读的方式读取Command对象获得的数据结果集,正是因为DataReader是以顺序的方式连续的读取数据,所有DataReader会以独占的方式打开数据库的连接 由于DataReader只执行读的操作(只读),并且每次只在内存缓冲区里存储结果集中的一条数据,所有使用DataReader的对象的效率比较高,如果要查询大量数据,同时不需要随机访问和修改数据,DataReader是优先的选择 DataReader 对象的常用属性 Fiel

  • asp.net SqlDataReader绑定Repeater

    一直以为不可以,原来是可以的,肤浅啊! 复制代码 代码如下: <%@ Page Language="C#" %> <%@ Import Namespace="System.Data.SqlClient" %> <%@ Import Namespace="System.Data" %> <script runat="server"> protected void Page_Load

  • DataReader、DataSet、DataAdapter和DataView使用介绍

    ADO.NET提供两个对象用于检索关系型数据并把它存储在内存中,分别是DataSet和DataReader.DataSet提供内存中关系数据的表现--包括表和次序.约束等表间的关系的完整数据集合.DataReader提供快速.只向前.只读的来自数据库的数据流. 使用DataSet时,一般使用DataAdapter(也可能是CommandBuilder)与数据源交互,用DataView对DataSet中的数据进行排序和过滤.DataSet可以被继承来建立强化类型的DataSet,用于暴露表.行.列

  • 详细说明asp.net中datareader 和 dataset 的区别

    1. 获取数据的方式    DataReader为在线操作数据, DataReader会一直占用SqlConnection连接,在其获得数据过程中其它操作不可以再使用SqlConnection连接对象. 复制代码 代码如下: while(datareader.read()){..............}dataview.datasource=datareader;dataview.databind(); DataSet为离线操作数据,DataSet会将数据一次性读入内存,然后断开连接,这时其它

  • DATASET 与 DATAREADER对象有什么区别

    DataReader和DataSet最大的区别在于,DataReader使用时始终占用SqlConnection(俗称:非断开式连接),在线操作数据库时,任何对SqlConnection的操作都会引发DataReader的异常.因为DataReader每次只在内存中加载一条数据,所以占用的内存是很小的.由于DataReader的特殊性和高性能,所以DataReader是只进的,你读了第一条后就不能再去读取第一条了. DataSet则是将数据一次性加载在内存中,抛弃数据库连接(俗称:断开式连接).

  • DataReader不能使用using的详细示例

    本文介绍了DataReader不能使用using的详细示例,分享给大家,具有如下: public static MySqlDataReader ExecuteMySqlReader(string sqlStr) { MySqlConnection conn = new MySqlConnection(MyConString); MySqlCommand cmd = new MySqlCommand(sqlStr, conn); try { conn.Open(); //执行CloseConnec

  • Linux crontab 命令格式与详细示例(推荐)

    基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4列表示月份1-12 第5列标识号星期0-6(0表示星期天) 第6列要运行的命令 crontab文件的一些例子: 30 21 * * * /usr/local/etc/rc.d/lighttpd restart 上面的例子表示每晚的21:30重启apache. 45 4 1,10,22 * * /usr/l

  • Pygame Event事件模块的详细示例

    目录 事件类型 事件处理方法 处理键盘事件 处理鼠标事件 事件(Event)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击.键盘敲击.游戏窗口移动.调整窗口大小.触发特定的情节.退出游戏等等,这些都可以看做是"事件",Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小,那么 Pygame 是如何处理这些事件的呢? 事件类型 Pygame 定义了一个专门用来处理事件的结构,即事件队列,该结构遵循遵循队列"先到先处理

  • 用Python爬取英雄联盟的皮肤详细示例

    目录 一.推理原理 二.推理代码 第一步:获取js字典 第二步:从 js字典中提取到key值生成url列表 第三步:从 js字典中提取到value值生成name列表 第四步:下载并保存数据 第五步:执行主程序 一.推理原理 1.先去<英雄联盟>官网找到英雄及皮肤图片的网址: lol.qq.com 2.从上面网址可以看到所有英雄都在,按下F12查看源代码,发现英雄及皮肤图片并没有直接给出,而是隐藏在JS文件中. 这时候需要点开Network,找到js窗口,刷新网页,就看到一个champion.j

  • Java使用HttpClient详细示例

    目录 准备环节 第一步:在pom.xml中引入HttpClient的依赖 第二步:引入fastjson依赖 详细使用示例 GET无参: GET有参(方式一:直接拼接URL): GET有参(方式二:使用URI获得HttpGet): POST无参: POST有参(普通参数): POST有参(对象参数): POST有参(普通参数 + 对象参数): 对评论区关注度较高的问题进行相关补充: 解决响应乱码问题(示例): 进行HTTPS请求并进行(或不进行)证书校验(示例): 相关方法详情(非完美封装): a

  • Beego中ORM操作各类数据库连接方式详细示例

    目录 beego中各类数据库连接方式 1.1 orm使用方式 a. 注册数据库驱动程序 b.注册数据库 c. 注册模型 1.2 操作示例 a. orm连接mysql b. orm连接sqlite3 c. orm连接 postgresql 1.3非orm连接方式 a. mysql b. sqlite3 c. postgresql d. mongodb e.sqlserver f.redis beego中各类数据库连接方式 beego 框架是优秀得go REST API开发框架.下面针对beego中

  • C++ 超详细示例讲解list的使用

    目录 一.list的介绍 list的介绍 二.list的使用 2.1 list的构造函数 2.2 list迭代器的使用 2.3 list相关的容量大小相关的函数 2.4 list数据的访问相关的函数 2.5 list的数据调整相关的函数 2.6 list中其他函数操作 一.list的介绍 list的介绍 list是可以以O(1)的时间复杂度任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针

  • Kotlin协程flowOn与线程切换超详细示例介绍

    目录 示例代码 一.flowOn方法 1.ChannelFlowOperatorImpl类 二.collect方法 1.ChannelFlowOperator类的collect方法 2.ChannelFlow类的collect方法 3.flow方法中代码的执行 4.接收flow方法发出的值 三.flowOn方法与流的融合 四.总结 示例代码 本文分析示例代码如下: launch(Dispatchers.Main) { flow { emit(1) emit(2) }.flowOn(Dispatc

  • react-router-dom v6 使用详细示例

    目录 一.基本使用 二.路由跳转 2.1 Link 组件 2.2 NavLink 组件 2.3 编程式跳转 三.动态路由参数 3.1 路径参数 路径匹配规则 兼容类组件 3.2 search 参数 四.嵌套路由 5.1 路由定义 5.2 在父组件中展示 5.3 在组件中定义 五.默认路由 六.全匹配路由 七.多组路由 八.路由重定向 九.布局路由 十.订阅和操作 history stack的原理 10.1 History对象 11.2 Location对象 state key 十一. 各类Rou

  • Spring @Autowired注解超详细示例

    目录 前言 一.依赖注入的方式 手动注入 自动装配 二.注解@Autowired的自动装配原理 @Autowired自动装配过程 实现原理 ①首先看看spring的源代码定义 ②核心逻辑在buildAutowiringMetadata中 ③InjectionMetadata类 ④ 实现注入逻辑 ⑤调用InjectionMetadata中的公共inject ⑥遍历调用protect的inject方法 前言 说明:我们今天要分享的是依赖注入(DI)通过自动装配的注解方式@Autowird注解方法的作

随机推荐