c# - 完成队列释放速度不够快

标签 c# oracle dispose freeze finalize

我有一个针对位于服务器上的 Oracle 数据库运行的 c# 3.5 框架 Windows 应用程序。

其中一种应用程序的顶部有八个选项卡。在每个选项卡的选项卡内容区域内是一个组合框。组合框在每个表单上显示相同的信息。当用户使用下拉菜单或键盘箭头更改组合框值时,八个选项卡区域将填充从 Oracle 中提取的数据。

基于现有程序的结构,每次更改组合框时,都会打开大约 20 个单独的 DB 连接。首先,调用大约 8 个将来自不同选项卡的数据保存到它们正确的表中。每个选项卡的内容都传递给数据库类以保存该选项卡的数据。其次,进行了大约 8 次数据库调用以根据组合框从表中加载选项卡。

澄清一下,这就像在任何选项卡上选择一个组合框来更改汽车型号。然后每个选项卡都会是“内部选项”“引擎选项”等内容。

然后进行几次数据库调用以根据 ID 锁定高级记录,这样其他人就无法同时编辑该特定记录。

总的来说,这个过程非常稳固。保存/加载时间非常快。我可以通过几乎即时的数据保存/加载在两个不同的组合框值之间来回切换。

问题来了

如果我来回旋转的速度足够快(一些用户也这样做过),整个程序就会挂起。没有崩溃,只是挂起。

在调试环境中重复此操作,我发现它总是停在同一行代码(一个简单的记录集分配(例如 CarModelInterior.Notes = Convert.ToString(myReader[6]);)

然后我发现垃圾收集器 (GC) 线程在后台运行,但每次都在同一个地方停止。

进入 RED-Gate 内存/性能监视器的安装。

我发现,我切换组合框值的速度越来越快,GC Finalizer 队列填满的速度也越快。最终,相同的 SQL 调用似乎位于列表的顶部。

输入我的假设和猜测。

我的想法是,要么打开的连接太多,但没有足够快地完成,要么某处正在锁定。

我可以说的是,整个程序中我的所有(每一个)数据库调用都使用“USING”语句,因此所有处理都是自动完成的。此外,所有(是的,我检查了整个应用程序),所有数据库调用都在主线程上。因此,为每个组合框值更改进行的所有 20 次左右的数据库调用都是按顺序进行的。至少就可能的单线程问题而言,这已经消除了锁定的可能性。

我还剩下什么?在这一点上,我放弃了太多的谷歌搜索并张贴在这里。 finalize queue 是否可能处理得不够快?还有其他想法吗?

最佳答案

OracleCommand 必须在资源被回收之前被 Disposed。 DbCommand ,通常是 Command 对象的基类,实现 IDisposable。相比之下,System.Data.SqlClient.SqlCommand 似乎不需要处理,因此它可能会导致开发人员忘记许多 DbCommand 实现确实需要处理。 如果未处理命令,则垃圾收集器最终将通过调用 Finalize 方法释放非托管资源(假设您的 Oracle Client 的 OracleCommand 实现覆盖了 object.Finalize)。

关于c# - 完成队列释放速度不够快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6128818/

相关文章:

sql - 如何查找一年中所有月份的第一个日期

C# - 我知道,我知道,关于 Dispose 的另一个问题(与设计更相关)!

c# - (.net) CriticalFinalizerObject - 它的真正作用是什么?

c# - 变量不持有值(value)

c# - 听wav文件C#

linux - 以用户 `sqlplus` 身份运行 `oracle` 时出错

sql - 在 HSQL 中刷新 View

c# - Dispose,什么时候调用?

c# - 任何示例项目都使用 DirectShow.NET 库在同一项目中捕获图像和视频?

c# - 部署在 AWS 上时 MySQL 表不存在