"using"块会在程序强制关闭时释放资源吗?

3

根据标题的问题。

我有一段代码可以做到这一点:

    using (SqlConnection dbcon = new SqlConnection(connectionString))
    using (SqlDataAdapter dataAdapter = new SqlDataAdapter(statement, dbcon))
    {
        dat_set = new System.Data.DataSet();

        dbcon.Open();
        dataAdapter.Fill(dat_set, name);  
    }

当我在数据适配器仍在填充数据集时强制退出程序,程序会冻结并停止响应。
我知道“using”块会在超出作用域时释放资源,但在强制终止的情况下,资源是否能得到优雅地释放?

1
更大的问题是:“为什么在数据适配器仍在填充时强制退出程序?” - Mitch Wheat
1
因为从用户的角度来看,他们应该能够在任何时候终止程序。 - gin
也许你的适配器填充数据所需时间太长了。考虑加载较小的数据集。或者使用分页... - Mitch Wheat
如果用户想关闭它,那么你可能需要一个单独的程序来填充数据集或者进行其他填充操作。这意味着你的客户端程序应该只是这个分离的 .exe 程序的“调用者”,并且不时地检查它的状态。 :) 这是我的建议。 - ken lacoste
@MitchWheat是的,我正在从数据库中获取大量数据。为了测试目的,我正在查询数据库中前1000000个结果到数据集中。你能否提供一个关于你提到的分页的在线资源链接? - gin
@kenlacoste 是的,将前端和后端组件分离将在未来完成。现在有点处于原型阶段。 - gin
2个回答

7
如果一个进程退出,所有本地资源(网络句柄、文件句柄等)都会被操作系统清除。我不认为“using”语句会在这里生效 - 我怀疑操作系统会强制终止线程,以致于无法自行完成清理工作。这意味着你仍然需要完成清理工作...但是,在使用“using”语句时可能不会发生任何刷新操作(例如在文件写入场景中)。

如果在线程中执行上述代码,调用 thread.abort() 方法是否会产生相同的结果?即操作系统进入执行本地资源清理的状态。 - gin
1
@gin:不,我相信 Thread.Abort 仍然会执行堆栈上的 finally 语句。(实际上,你可以捕获 ThreadAbortException 并重置它,如果你真的想这样做的话。)终止单个线程并不会让操作系统进行任何清理,因为资源代码可能正在不同的线程中使用。 - Jon Skeet
1
我只是出于好奇跑了一些测试。Thread.AbortAppDomain.UnloadEnviorment.FailFast都会导致finally块被执行(我很确定Thread.Abort会这样做,但对于最后两个还是相当惊讶的)。 - Scott Chamberlain

1
using语句只是使用try-finally块的简易方式。所以真正的问题是,如果你强制退出程序,finally块会运行吗?答案是“不会”。
然而,所有外部句柄(包括您在代码示例中打开的数据库连接)都会在程序终止时释放,因此即使finally块从未运行,您也不会有孤立的数据库连接。当连接终止时,任何仍处于打开状态的事务都将被回滚和撤消(即使您没有显式启动事务,所有请求都被包装在隐式事务中)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接