我有针对位于服务器上的 Oracle DB 运行的 ac# 3.5 框架 Windows 应用程序。
其中一种应用程序的顶部有八个选项卡。每个选项卡的选项卡内容区域内都有一个组合框。组合框在每个表单上显示相同的信息。当用户使用下拉箭头或键盘箭头更改组合框值时,八个选项卡区域将填充从 Oracle 提取的数据。
根据现有程序的结构,每次更改组合框时,都会打开大约 20 个单独的 DB 连接。首先,调用大约 8 个来将不同选项卡中的数据保存到正确的表中。每个选项卡的内容都传递给一个 DB 类以保存该选项卡的数据。其次,基于组合框,大约进行了 8 次 DB 调用以从表中加载选项卡。
澄清一下,这就像在更改汽车型号的任何选项卡上选择一个组合框。然后每个选项卡都会是“内部选项”“引擎选项”等内容。
然后进行几个数据库调用以根据 ID 锁定高级记录,这样其他人就不能同时编辑该特定记录。
总的来说,这个过程非常可靠。保存/加载时间非常快。我可以通过几乎即时的数据保存/加载在两个不同的组合框值之间来回切换。
那么问题来了
如果我来回旋转足够快(有几个用户也这样做了),整个程序就会挂起。没有崩溃,只是挂起。
在调试环境中重复此操作,我发现它总是停在同一行代码上(一个简单的记录集分配(例如 CarModelInterior.Notes = Convert.ToString(myReader[6]);)
然后我发现垃圾收集器(GC)线程在后台运行,但每次也都停在同一个地方。
进入安装 RED-Gate 内存/性能监视器。
我发现切换组合框值的速度越来越快,GC 终结器队列填满的速度也越快。最终,似乎同一个 SQL 调用位于列表的顶部。
输入我的假设和猜测。
我的想法是,要么打开了太多连接并且没有足够快地完成,要么某处有锁。
我能说的是,整个程序中我的所有(每一个)数据库调用都使用“USING”语句,因此所有处理都是自动完成的。此外,所有(是的,我检查了整个应用程序),所有数据库调用都在主线程上。因此,为每个组合框值更改进行的所有 20 次左右的 DB 调用都是按顺序进行的。至少就可能的单线程问题而言,这消除了锁定的可能性。
我还剩下什么?在这一点上,我已经放弃了太多的谷歌搜索并在这里发布。是否有可能完成队列的处理速度不够快?还有其他想法吗?