我有一个c#3.5框架Windows应用程序,它针对位于服务器上的Oracle数据库运行。
该应用程序的一种形式在顶部有八个选项卡。在每个标签的标签内容区域内是组合框。组合框在每个表单上显示相同的信息。当用户使用下拉列表或键盘箭头更改组合框值时,将使用从Oracle中提取的数据填充八个选项卡区域。
根据现有程序的结构,每次更改组合框时,都会打开大约20个单独的DB连接。首先,调用大约8个来将不同选项卡中的数据保存到正确的表中。每个选项卡的内容都传递给DB类以保存该选项卡的数据。其次,基于组合框,从表中加载大约8个DB调用来加载选项卡。
澄清一下,就像在改变汽车模型的任何标签上挑选一个组合框。然后每个标签都会出现“内部选项”,“引擎选项”等等。
然后进行几次数据库调用以根据ID锁定高级记录,这样其他任何人都无法同时编辑该特定记录。
整个过程非常可靠。保存/加载时间非常快。我可以在几个即时数据保存/加载的情况下在两个不同的组合框值之间来回切换。
然后出现问题
如果我来回快速旋转(一些用户也做过),整个程序都会挂起。没有崩溃,只是挂起。
在debug environ中重复这一点,我发现它始终停在相同的代码行上(一个简单的记录集赋值(例如CarModelInterior.Notes = Convert.ToString(myReader [6]);)
然后我发现垃圾收集器(GC)线程在后台运行,但每次都停在同一个地方。
输入RED-Gate Memory / Performance监视器的安装。
我发现更快更快地切换组合框值,GC Finalizer队列填满的速度越快。最终,似乎同一个SQL调用位于列表的顶部。
输入我的假设和猜测。
我的想法是,要么打开太多连接,要么没有足够快地完成任务,或者某个地方有锁定。
我可以说的是,整个程序中我的数据库调用的所有(每一个都是怪异的)使用“USING”语句,因此所有处理都会自动完成。此外,ALL(在是的,我检查了整个应用程序),所有数据库调用都在主线程上。因此,为每个组合框值变化进行的所有20个或更多个DB调用都是按顺序进行的。这至少就可能的单线程问题而言已经消除了锁定的可能性。
我还剩下什么?在这一点上,我已经放弃并在这里发布了如此多的谷歌搜索。是否有可能终结队列的处理速度不够快?还有其他想法吗?
答案 0 :(得分:1)
在回收资源之前必须先部署OracleCommand。 DbCommand,通常是Command对象的基类,实现了IDisposable。相比之下,System.Data.SqlClient.SqlCommand似乎不需要处理,因此它可能导致开发人员忘记许多DbCommand实现确实需要处理。 如果未处理命令,则垃圾收集器最终将通过调用Finalize方法释放非托管资源(假设Oracle Client的OracleCommand实现覆盖object.Finalize)。