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