有没有办法强制应用程序作为单线程运行?

Ang*_*ore 8 c# multithreading com+ desktop-application

我们有一个我们正在支持的旧项目,并且最有可能由于多线程而出现问题.原始实现者通过Thread.sleep在执行有问题的部分之前执行a 来"修复"它.该解决方法有效,但由于该部分位于循环thread.sleep内,因此该部分完成所需的时间增加了几分钟.

在过去的一个月里,我们一直在试验较低的睡眠值,但我们希望找到根本原因.在我们的调查过程中,我们lock在私人物品上进行操作,无论我们觉得哪有帮助.我们寻找任何可能产生额外线程的东西 - 没有找到.没有Thread.start和ThreadPool用法.让我们感到困惑的是,在调试过程中,我们发现我们的主要线程在大约8个其他线程的中间,我们不知道是谁产生了它们.这些是后台线程,所以我首先想到的是线程池,但正如我在代码中提到的那样.

它是.net 2.0所以没有Async.这只是更大的应用程序的一部分,所以它是一个Windows服务,但我们将其作为CMD运行,以便能够轻松调试它主要的应用程序本身是一个Windows窗体桌面应用程序.如果有任何帮助,它也使用COM +组件.

我试过[STA]而不是[MTA].同样按上述方式锁定. MemoryBarrier也是.

我们仍然遇到了这个问题.

问题基本上是损坏的数据集和它们不应该存在的对象中的空值.它发生在大约每25-100次迭代一次,因此复制不是直接的,但我们已经设计了一个专门针对这个问题的测试来尝试重现它.

所有这些都指向了线程问题的方向.

回到最初的问题 - 谁可能通过产生这些额外的线程,我们如何防止这些线程被创建?

在此输入图像描述

请注意标有红色的线程 - 这些是后台线程,据我们所知,在代码中没有提到它们.

屏幕截图中的可疑线程正在主动修改其中的cols dataset.问题是 - 调用SetColValueOnRow线程正在执行的函数的方法是典型的,不使用任何类型的线程.

此应用程序的CPU关联性设置为1 Core [原始解决方案的一部分]

谢谢

编辑:数据库是oracle 12c,但我们面临的问题是在写入数据库之前发生的.它们通常发生在DataSet中,每隔几次测试迭代就可以擦除整个记录或一些列

Bob*_*yan 3

我认为您需要调查 Thread.sleep 为何有效。听起来代码本身并没有产生额外的线程,但您必须遍历整个代码库才能找到答案 - 包括 COM+ 组件。

因此,我要做的第一件事就是在调试中启动程序,然后按 F10 键单步执行程序。然后打开线程调试窗口,看看您是否看到与问题中给出的线程数相同的线程数。如果您这样做,那么这些只是线程池中的线程,您的问题可能与多个线程无关。

如果您没有看到相同数量的线程,请尝试在程序的各个阶段设置断点,看看是否可以找到创建这些线程的位置。当您找到它们的创建位置时,您可以尝试在此时添加一些锁定。但是,您的问题仍然可能不是由多个线程损坏内存引起的。您应该进行调查,直到确信问题是由于多线程或其他原因造成的。

我怀疑该问题可能与一个或多个 COM+ 组件有关,或者代码可能正在调用某些长时间运行的数据库存储过程。无论如何,我怀疑 Thread.sleep 起作用的原因是因为它为可疑组件提供了足够的时间来完成其操作,然后再开始下一个操作。

如果这个理论是正确的,那么它表明操作之间存在一些交互,并且当 Thread.Sleep 被赋予足够大的值以允许操作完成时 - 不存在交互问题。这也表明 COM+ 组件之一可能正在异步执行某些操作。解决方案可能是在 COM+ 组件代码中使用锁或临界区。另一个想法是重新设计导致问题的代码部分,以允许同时进行多个操作。

因此,您遇到的问题可能不是由于您正在查看的 C# 代码中的多个线程造成的,而可能是由于长时间运行的操作造成的,如果在开始下一个操作之前没有给予足够的时间来完成该操作,该操作有时会失败。这可能是由于 C# 代码中的多个线程造成的,也可能不是。