Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 完成队列释放不够快_C#_Oracle_Dispose_Freeze_Finalize - Fatal编程技术网

C# 完成队列释放不够快

C# 完成队列释放不够快,c#,oracle,dispose,freeze,finalize,C#,Oracle,Dispose,Freeze,Finalize,我有一个c#3.5框架Windows应用程序,它运行在服务器上的Oracle DB上 应用程序的其中一个表单的顶部有八个选项卡。每个选项卡的选项卡内容区域中都有一个组合框。组合框在每个表单上显示相同的信息。当用户使用下拉或键盘箭头更改组合框值时,八个选项卡区域将填充从Oracle提取的数据 根据现有程序的结构,每次更改组合框时,都会打开大约20个单独的DB连接。首先,调用大约8将不同选项卡中的数据保存到正确的表中。每个选项卡的内容都传递给一个DB类,用于保存该选项卡的数据。其次,根据combob

我有一个c#3.5框架Windows应用程序,它运行在服务器上的Oracle DB上

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

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

澄清一下,这就像在任何选项卡上选择一个组合框来更改汽车模型一样。然后,每个选项卡都是“内饰选项”、“发动机选项”等内容

然后进行两次DB调用,根据ID锁定高级记录,这样其他人就不能同时编辑该特定记录

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

然后问题来了

如果我来回旋转的速度足够快(有几个用户也这么做了),整个程序就会挂起。没有碰撞,只是挂断

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

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

进入红门内存/性能监视器的安装。

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

输入我的假设和猜测。

我的想法是,要么打开的连接太多,完成的速度不够快,要么某个地方出现了锁

我能说的是,在整个程序中,我的所有DB调用(每一个和每一个奇怪的调用)都使用“USING”语句,所以所有的处理都是自动完成的,所有DB调用都在主线程上。因此,为每个combobox值更改而进行的大约20个DB调用都是按顺序进行的。这至少消除了锁定的可能性,因为这是一个可能的单线程问题


我还剩下什么?在这一点上,我放弃了这么多的谷歌搜索,并发布在这里。是否有可能最终确定队列处理速度不够快?还有其他想法吗?

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

问题是为什么(使用什么对象?)终结队列首先是否已满?如果正在处置资源,Dispose调用应执行
GC.SuppressFinalize()
这可以避免这个问题。碎玻璃已经做出了敏锐的观察。另外,是否有任何锁定原语可能会在共享资源上死锁?也许,它位于数据访问层(您没有提到;它是哪一个?),红门程序中列出的所有值都会被“未处理的对象”过滤掉所有的都是OracleCommand对象。当它挂起时,列表顶部的一个(带有几个内存快照以确认它没有清除队列)是一个删除SQL。因为我可以复制错误,而且它是单线程的,所以它怎么可能是锁定错误?(无辜的问题)此外,所有语句都使用:using(myConnection=new OracleConnection)(ConnectDB))。因此没有理由使用我自己的dispose。到oracle DB的连接字符串只是数据源、用户id和密码。您是同时处理OracleCommands还是仅处理连接?如果不是,这可能是您的问题(最容易在使用块中使用它们)。