打破砂锅问到底,Close()和Dispose()的深入理解

zcxverygood123456 2010-09-19 12:27:26
网上查看了很多资料,有几个疑惑:
前提:
Close 是停业整顿,停业了,可以通过公关,再重开,物还是原来的物;只是关闭而已,没有释放真正的释放资源,可以重新打开;
Dispose 是炸毁,炸毁了,想再开张,就只有重头建起;是把对象销毁,将不再存在;

问题1、什么地方会这么用?比如新闻的显示页,我是用DataReader这个SqlConnection 先Open(),然后再Close();
这个地方到底我是用Close还是Dispose;还是两个一起用(先用Close再接着加Dispose)。

问题2、我打开了新闻的显示页后,可能第二天可能我还要打开,或者还有很多人也可能同时在看这条新闻,那么到底我是Close还是Dispose?我这里用Close有什么好处,要是用Dispose有什么用?是不是我Dispose炸毁了,第二天后我就不能打开这条新闻了?

问题3、实际一点(理论就不必多说了),哪些场合需要Close? 哪些场合需要Dispose?或者是哪些场合必须两者都要?
最好能举例子说明
...全文
571 21 打赏 收藏 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2011-07-22
  • 打赏
  • 举报
回复
ri.Close();riDispose();conn.Close();
「已注销」 2011-07-22
  • 打赏
  • 举报
回复
学习了...我感觉还是并用好点..
w4bjx 2010-09-26
  • 打赏
  • 举报
回复
mark~!!~!~!~
nageboy 2010-09-20
  • 打赏
  • 举报
回复
推荐一篇文章,希望你能顿悟

c# GC管理
凤凰涅檠 2010-09-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dalmeeme 的回复:]

问题二:对每个浏览者分别创建不同的对象,即使Dispose也只是销毁了某个浏览者对应的数据连接对象,不会影响别人的。浏览者下次再浏览会重新实例化对象。

[/Quote]


这个我不是很明白,难道每个 客户端请求的是不同的 服务器端吗?每个浏览者都会有不同的对象,这句怎么理解
dengxiao1981 2010-09-20
  • 打赏
  • 举报
回复
学习...
zcxverygood123456 2010-09-20
  • 打赏
  • 举报
回复
总结下来,有几个问题没弄懂:
第一个问题:Close()方法只是关闭了连接,然后这个连接被存储到连接池,所以在调用Close()方法以后,还是可以再通过 Open()方法来打开连接的
======================
什么情况用到呢?
一般我是先Open()再Close()就完了,
没有过Open()再Close(),然后再Open()的情况,
比如打开新闻显示页,用DataReader这个SqlConnection 先Open(),然后再Close();就可以看新闻了,这个地方没必要把这个连接被存储到连接池,因为我没必要再通过 Open()方法来打开连接了。
所以不知这个“可以再通过 Open()方法来打开连接”有什么用?

第二个问题:打个比方说,你用浏览器上csdn首页,当把网页html流发送给浏览器后不久html流就关闭了,相当于Dr1.Close();当你把浏览器关闭或者跳到别的网站,那么网站连接也关闭了,相当于myCmd1.Connection.Close()。
============
那么这些关闭是否正在意义上的释放资源呢?

第三个问题:1、还有就是:WEB.config 里面:在数据库连接加 Max Pool Size = 512 这里的意思是不是最大连接数为512个,如果超过了,服务器怎么处理呢?
2、DataReader是独占连接的,比如说最大连接设100,假设有100个人同时使用DataReader正在读取数据库内容,那么当第101人读取的时候,连接池中的连接已经没有了,Connection对象的Close()方法,这是不行的,因为Close()方法仅仅是关闭连接,但这个连接没有释放,还是被这个对象占用,要释放必须使用Connection的Dispose()方法显式释放连接才可以,否则这个对象占用的连接只能等到垃圾收集的情况下才能被释放。这种情况肯定会出现“超时时间已到”的错误。
-----------
这是我在网上找到,这样的理解到底对不对?

第四个问题:Close是关闭数据连接,但DataReader对象还在
===================
那么对正在运行的网站有没有影响?
因为前几天我搞忘记了加Close(),恰巧这个页面有20多个DataReader,接连打开这个页面几次后,就出现“超时时间已到。在从池中获取连接之前超时时间已过。”,后来我加了Close()后就不会出现了。
但想优化再优化,是否也把Dispose()加进去是否能更好?

第五个问题:SqlCommand myCmd1 = new SqlCommand(mySel, myConn);
myCmd1.Connection.Open();
SqlDataReader Dr1 = myCmd1.ExecuteReader();
Dr1.Read();
string Count = Dr1["iCount"].ToString();
Dr1.Close();
myCmd1.Connection.Close();
==========================
以上代码:我通过ExecuteReader()该命令得出了结果Dr1["iCount"].ToString();
那么接下来程序用这个结果来判断做其它事情了,那么这个时候myCmd1.Connection.Close();取到什么作用?“只是关闭而已,没有释放真正的释放资源,可以重新打开;
”我已经得到我的结果了数据了,我还需要打开吗?
zcxverygood123456 2010-09-20
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 nageboy 的回复:]
推荐一篇文章,希望你能顿悟

c# GC管理
[/Quote]
===================
此页面打不开
dalmeeme 2010-09-19
  • 打赏
  • 举报
回复
不加Dispose()的话DataReader对象还会在服务器内存中存在,但只要创建对象的外层的方法体执行完毕,DataReader应该就释放了吧。如果方法体很大而数据操控在很前面,后面还有很多别的东西要执行,那就操控完后马上Dispose,否则我觉得也没必要。
zcxverygood123456 2010-09-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 dalmeeme 的回复:]
打个比方说,你用浏览器上csdn首页,当把网页html流发送给浏览器后不久html流就关闭了,相当于Dr1.Close();当你把浏览器关闭或者跳到别的网站,那么网站连接也关闭了,相当于myCmd1.Connection.Close()。
[/Quote]
============
那么这些关闭是否正在意义上的释放资源呢?
神码浮云 2010-09-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhangaijiang 的回复:]
很多人都认为Close()方法内部会调用Dispose()方法,所以并没有本质的区别!实际上这个看法不是很准确,对有些类来说,的确Close()和Dispose()没有本质区别,但是对有些类来说并非如此!
首先,让我们看看我们最常使用的SqlConnection的Close()方法和Dispose()方法的区别:
SqlConnection类的Dispose()方法是继承于Compon……
[/Quote]

很好, 学习学习 ..
zcxverygood123456 2010-09-19
  • 打赏
  • 举报
回复
1、还有就是:WEB.config 里面:在数据库连接加 Max Pool Size = 512 这里的意思是不是最大连接数为512个,如果超过了,服务器怎么处理呢?
2、DataReader是独占连接的,比如说最大连接设100,假设有100个人同时使用DataReader正在读取数据库内容,那么当第101人读取的时候,连接池中的连接已经没有了,Connection对象的Close()方法,这是不行的,因为Close()方法仅仅是关闭连接,但这个连接没有释放,还是被这个对象占用,要释放必须使用Connection的Dispose()方法显式释放连接才可以,否则这个对象占用的连接只能等到垃圾收集的情况下才能被释放。这种情况肯定会出现“超时时间已到”的错误。
-----------
这是我在网上找到,这样的理解到底对不对?
dalmeeme 2010-09-19
  • 打赏
  • 举报
回复
打个比方说,你用浏览器上csdn首页,当把网页html流发送给浏览器后不久html流就关闭了,相当于Dr1.Close();当你把浏览器关闭或者跳到别的网站,那么网站连接也关闭了,相当于myCmd1.Connection.Close()。
zcxverygood123456 2010-09-19
  • 打赏
  • 举报
回复
dalmeeme(无机战士)

Close是关闭数据连接,但DataReader对象还在
===================
那么对正在运行的网站有没有影响?
因为前几天我搞忘记了加Close(),恰巧这个页面有20多个DataReader,接连打开这个页面几次后,就出现“超时时间已到。在从池中获取连接之前超时时间已过。”,后来我加了Close()后就不会出现了。
但想优化再优化,是否也把Dispose()加进去是否能更好?
zcxverygood123456 2010-09-19
  • 打赏
  • 举报
回复
比如:
SqlCommand myCmd1 = new SqlCommand(mySel, myConn);
myCmd1.Connection.Open();
SqlDataReader Dr1 = myCmd1.ExecuteReader();
Dr1.Read();
string Count = Dr1["iCount"].ToString();
Dr1.Close();
myCmd1.Connection.Close();
==========================
以上代码:我通过ExecuteReader()该命令得出了结果Dr1["iCount"].ToString();
那么接下来程序用这个结果来判断做其它事情了,那么这个时候myCmd1.Connection.Close();取到什么作用?“只是关闭而已,没有释放真正的释放资源,可以重新打开;
”我已经得到我的结果了数据了,我还需要打开吗?
===============
说明一下:以上代码的意思是在登录的时候,先判断用户名是否存在,即如果Count==“0”的就不存在的意思。
我这时候已经得到string Count 数据了,如果我用Dispose炸毁了,第二天后我就不能再用了。
或是我理解错了。
dalmeeme 2010-09-19
  • 打赏
  • 举报
回复
问题一:Close是关闭数据连接,但DataReader对象还在,可能要过较长时间才会被垃圾回收。Dispose是要求马上回收。
问题二:对每个浏览者分别创建不同的对象,即使Dispose也只是销毁了某个浏览者对应的数据连接对象,不会影响别人的。浏览者下次再浏览会重新实例化对象。
问题三:Close是必须用的,Dispose可用可不用,如果负荷流量大就用Dispose。
zhangaijiang 2010-09-19
  • 打赏
  • 举报
回复
很多人都认为Close()方法内部会调用Dispose()方法,所以并没有本质的区别!实际上这个看法不是很准确,对有些类来说,的确Close()和Dispose()没有本质区别,但是对有些类来说并非如此!
首先,让我们看看我们最常使用的SqlConnection的Close()方法和Dispose()方法的区别:
SqlConnection类的Dispose()方法是继承于Component类的,源代码是这样的:
public void Dispose() {
Dispose(true); //调用Dispose的一个带参数的重载
GC.SuppressFinalize(this); //请求系统不要调用指定对象的终结器。
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
lock(this) {
if (site != null && site.Container != null) {
site.Container.Remove(this);
}
if (events != null) {
EventHandler handler = (EventHandler)events[EventDisposed];
if (handler != null) handler(this, EventArgs.Empty);
}
}
}
}
SqlConnection类的Close()方法在MSDN中的说明是这样的:
关闭与数据库的连接。这是关闭任何打开连接的首选方法。 如果 SqlConnection 超出范围,则不会将其关闭。因此,必须通过调用 Close 或 Dispose 显式关闭该连接。Close 和 Dispose 在功能上等效。如果连接池值Pooling 设置为 true 或 yes,则基础连接将返回到连接池。另一方面,如果 Pooling 设置为 false 或 no,则会关闭到服务器的基础连接。
看说明好象是Close()方法和Dispose()方法是类似的,实际上只是在关闭连接这个功能上等效,让我们看看Close ()方法的源代码:
override public void Close() {
IntPtr hscp;
Bid.ScopeEnter(out hscp, "<sc.SqlConnection.Close|API> %d#" , ObjectID);
try {
SqlStatistics statistics = null;

RuntimeHelpers.PrepareConstrainedRegions();
try {
#if DEBUG
object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot);

RuntimeHelpers.PrepareConstrainedRegions();
try {
Thread.SetData(TdsParser.ReliabilitySlot, true);
#endif //DEBUG
statistics = SqlStatistics.StartTimer(Statistics);

// The lock here is to protect against the command.cancel / connection.close

race condition
// The SqlInternalConnectionTds is set to OpenBusy during close, once this

happens the cast below will fail and
// the command will no longer be cancelable. It might be desirable to be

able to cancel the close opperation, but this is
// outside of the scope of Whidbey RTM. See (SqlCommand::Cancel) for other

lock.
lock (InnerConnection) {
InnerConnection.CloseConnection(this, ConnectionFactory);
}
// does not require GC.KeepAlive(this) because of OnStateChange

if (null != Statistics) {
ADP.TimerCurrent(out _statistics._closeTimestamp);
}
#if DEBUG
}
finally {
Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue);
}
#endif //DEBUG
}
catch (System.OutOfMemoryException e) {
Abort(e);
throw;
}
catch (System.StackOverflowException e) {
Abort(e);
throw;
}
catch (System.Threading.ThreadAbortException e) {
Abort(e);
throw;
}
finally {
SqlStatistics.StopTimer(statistics);
}
}
finally {
SqlDebugContext sdc = _sdc;
_sdc = null;
Bid.ScopeLeave(ref hscp);
if (sdc != null) {
sdc.Dispose();
}
}
}
可以看到Close()方法并没有调用Dispose()方法,虽然有一行sdc.Dispose();,但是这只是释放SqlDebugContext

实例,和SqlConnection.Dispose()方法没有关系!

那么区别在哪里呢?
Close()方法只是关闭了连接,然后这个连接被存储到连接池,所以在调用Close()方法以后,还是可以再通过 Open()方法来打开连接的而调用Dispose()方法以后,这个连接就不能在使用了!
还有一个重要区别就是,当Close()方法并没有调用GC.SuppressFinalize(this);,这导致的直接后果就是在垃圾回收的时候需要进行终止化操作,这会导致这个实例的“代龄”提升,从而极大的延迟这个对象的回收时间!
针对SqlConnection这个类来说,如果以后还需要使用这个连接可以使用Close()方法临时关闭连接,如果以后不需要使用这个连接了,可以优先选用Dispose()方法来释放资源,当然你可以使用using关键字来简化这个过程,
OleDbConnection类和OdbcConnection类的源代码我没有找到,但是应该和SqlConnection类是类似的!
让我们在看一个我们常用的类,看看FileStream类的Close()方法和Dispose()方法有什么区别:
FileStream类的Close()方法是继承于Stream类的,源代码是这样的:
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
FileStream类的Dispose()方法是继承于Stream类的,源代码是这样的:
public void Dispose()
{
Close();
}
是一个标准的Dispose模式的实现,Close()方法调用的是带参数的Dispose方法,然后调用GC.SuppressFinalize(this);请求系统不要调用指定对象的终结器。而Dispose()方法直接调用Close()方法!
对于FileStream类来说,Close()方法和Dispose()方法是没有区别!
MSDNXGH 2010-09-19
  • 打赏
  • 举报
回复
比如,con.close();con.disponse();
MSDNXGH 2010-09-19
  • 打赏
  • 举报
回复
安全起见。。可以两者一起用,
村长_乐 2010-09-19
  • 打赏
  • 举报
回复
学习...
加载更多回复(1)
源码直接下载地址: https://pan.quark.cn/s/b2e30c4b4277 依据所提供的文件资料,可以总结出以下核心内容: 1. 华硕玩家国度x79 R4G主板属于高端级别的主板,归类于华硕玩家国度系列中的RAMPAGE IV GENE型号。该主板主要面向高端用户及游戏爱好者,具有卓越性能的特点。 2. 华硕玩家国度x79 R4G主板的使用指南采用简体中文版本,并以PDF格式发布。用户手册全面地阐述了该主板的操作方法和各项功能。 3. 版权声明明确指出,本手册包含的所有内容均受到著作权法的保护。未经华硕电脑股份有限公司(简称“华硕”)的许可,禁止进行任何形式的复制、剽窃、翻译或分发。 4. 免责声明具体说明,华硕提供的用户手册依照其发布时的状态呈现,不提供任何明示或暗示的保证。用户使用手册所面临的风险需自行承担,且华硕不对使用手册后的任何结果或信息的精确性或可靠性提供保证。 5. 用户手册中强调,使用本手册后可能引发的风险和损失,涵盖但不限于利益损失、业务中断、数据遗失或其他经济上的损失,华硕及其授权人员、雇员等均不承担相应责任。 6. 华硕拥有随时更新用户手册的权力。当产品规格或驱动程序发生变化时,用户手册将进行相应的修订。用户可以通过华硕的客户服务网站或直接联络华硕电脑客户关怀中心以获取最新版本的信息。 7. 第三方产品名称或内容的所有权和知识产权归属于各自的所有者,并受到相关法律法规的保护。 8. 在华硕的保修政策中,若产品经历过未经华硕授权的维修、规格调整、部件更换或其他未授权操作,或者产品序列号模糊不清或遗失,产品将不再享受华硕的保修和服务。 9. 华硕供应的主板及显卡产品在中国大陆地区(不包括港澳台地区)实施三年免费保修服务及全国联保服务...
内容概要:本文围绕2026年高教社杯全国大学生数学建模竞赛B题“无线电干扰源的快速自动定位与清除”提供了一套完整的数学建模、算法实现与论文撰写的免费资源。该资源由“荔枝科研社”出品,依托一个涵盖智能优化算法、机器学习、深度学习、信号处理、通信技术、电力系统管理等多个前沿领域的综合性科研资源共享平台。文档以MATLAB和Python为主要工具,聚焦于复杂工程问题的建模与求解,尤其在干扰源定位、状态估计、路径规划及优化调度等方面具有突出的应用价值。资源不仅包含竞赛题目解析,还提供了大量可复现的代码实例与技术文档,旨在帮助用户深入理解算法原理并提升科研实践能力。; 适合人群:具备一定编程基础,特别是熟练掌握MATLAB或Python语言的本科生、研究生,正在备战数学建模竞赛的学生,以及从事通信、信号处理、电力系统等相关领域研究的科研人员和技术开发者。; 使用场景及目标:①为参赛学生提供B题的完整解题思路、模型构建方法与代码实现路径,加速竞赛准备进程;②为科研工作者提供高质量、可复现的算法代码与技术参考,推动智能算法在无线通信、应急响应、环境监测等实际场景中的应用研究;③促进跨学科技术融合,支持教学、科研与工程实践的协同发展。; 阅读建议:建议读者结合文中提供的网盘链接与《荔枝科研社资源整理目录》系统性地查阅资料,优先选择与自身研究方向契合的技术模块进行深入学习,并动手运行代码以验证算法效果。同时推荐关注微信公众号“荔枝科研社”以获取持续更新的技术内容与社群支持。
代码下载链接: https://pan.quark.cn/s/a4b39357ea24 Unity作为一个功能强大的跨平台游戏开发工具,被普遍应用于构建二维和三维游戏、各类应用程序以及虚拟现实体验。在本次“Unity与百度地图集成测试项目”中,我们将研究如何将Unity平台与百度地图API相结合,以便实现地理位置相关服务。百度地图是中国首屈一指的在线地图服务供应商,它提供了丰富的地图信息资源以及精准的定位和导航服务,这使得百度地图成为Unity开发者在开发地理相关软件时的首选方案。 我们需要在Unity开发环境中导入百度地图SDK。一般而言,这一流程包含从百度地图官网获取SDK安装包,将其解压后添加至Unity项目的Assets文件夹中。在该MapTest项目中,或许已经预置了必要的库文件和执行脚本,从而支持我们迅速开展地图功能的集成工作。 集成百度地图的核心流程包括以下环节: 1. **开发者账户的注册**:在运用百度地图API之前,必须在百度地图开放平台创建一个开发者账户,并生成一个应用以获取API密钥。此密钥将在后续的代码设置中发挥作用,用于确认应用的身份认证。 2. **Android/iOS系统的配置**:在Unity开发环境中,我们需要针对Android和iOS操作系统进行个性化的设置。对于Android系统,需要在`Plugins/Android`文件夹中配置相应的依赖库(例如`libBaiduMapSDK_base.jar`等),并在`AndroidManifest.xml`文档中声明必要的权限。对于iOS系统,需要将相关SDK文件导入Xcode工程,并调整Info.plist配置文件。 3. **地图的初始化设置**:在Unity开发环境中,可...

62,271

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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