有没有一种方法可以强制应用程序以单线程方式运行?

10
我们正在支持一个旧项目,由于多线程问题,可能会出现问题。原始实现者通过在执行有问题的部分之前进行Thread.sleep来“修复”它。 这个解决方法有效,但由于该部分位于循环内,thread.sleep会使该部分完成所需时间增加多分钟。
在过去的一个月中,我们一直在尝试使用更低的睡眠值,但我们希望找到根本原因。在调查期间,我们在所有感觉有帮助的私有对象上进行了lock。 我们寻找任何可能产生额外线程的东西-但没有找到。 没有Thread.start和ThreadPool使用。 让我们困惑的是,在调试过程中,我们发现我们的主线程处于大约8个其他线程的中间,而我们不知道谁生成了它们。 这些是后台线程,所以我首先想到的是线程池,但正如我提到的,在代码中没有提到它。
它是.net 2.0,因此没有Async。 这只是更大应用程序的一部分,因此它是Windows服务,但我们将其作为CMD运行,以便轻松调试它。主要应用程序本身是Windows窗体桌面应用程序。 它还使用COM+组件,如果有任何帮助的话。
我已经尝试使用[STA]替代[MTA]。 还有如上所述的锁定。 还有MemoryBarrier
我们仍然遇到问题。
问题基本上是数据集损坏和对象中的空值,这些空值不应该存在。 它大约每25-100次迭代发生一次,因此复制不是直接的,但我们已经设计了一个专门用于此问题的测试来尝试复制它。
所有这些都指向线程问题的方向。
回到最初的问题 - 谁可能会产生这些额外的线程,我们如何防止创建这些线程?

enter image description here

请注意标有红色的线程 - 它们是后台线程,在代码中我们没有看到任何与它们相关的提及。
屏幕截图中可疑的线程正在积极修改 dataset 中的列。问题在于,调用执行该线程的 SetColValueOnRow 函数的方法是典型的,并且不使用任何类型的线程。
此应用程序的 CPU 亲和力设置为 1 核心 [原始工作区的一部分]
谢谢
编辑:数据库是 Oracle 12c,但我们面临的问题发生在写入数据库之前。它们通常发生在 DataSets 中,其中整个记录或其几列可能会在每几次测试迭代中被清除。

什么类型的应用程序(WinForms,服务,...)? - pm100
这只是一个更大应用程序的一部分,因此它是一个Windows服务,但我们将其作为CMD运行,以便能够轻松调试它。 主要应用程序本身是一个Windows窗体桌面应用程序。 - AngelicCore
1
“到底是谁在产生这些额外的线程,我们该如何防止它们被创建?”这才是原始问题吗?你的标题是“有没有办法强制应用程序以单线程方式运行?”,这似乎是一个完全不同(且不可行)的问题。正常的.NET程序有许多原因会创建线程,所以这可能就是你看到的情况。甚至不清楚“强制应用程序以单线程方式运行”意味着什么。好像有一种方法可以将多个执行序列塞入一个线程中? - Peter Duniho
1
你可以尝试运行Visual Studio的性能测试工具;录制并注意当线程像那些让物理学家夜不能寐的恼人的量子泡沫一样自发出现时。 - user585968
显示剩余10条评论
1个回答

3
我认为你需要调查Thread.sleep的作用原理。代码本身似乎并没有产生额外的线程,但你需要检查整个代码库,包括COM+组件。
所以我建议首先在调试模式下启动程序,按F10键逐步执行程序。然后打开线程调试窗口,看看是否与你提出的问题中给出的线程数量大致相同。如果是,那么这些只是来自线程池的线程,你的问题可能与多线程无关。
如果你没有看到相同数量的线程,请在程序的各个阶段设置断点,看看能否找到创建这些线程的地方。当你找到它们被创建的地方时,可以尝试在那个点添加一些锁定。但是,你的问题仍然可能不是由多个线程破坏内存引起的。你应该进行调查,直到你确信问题是由多个线程或其他原因引起的。
我怀疑问题可能与一个或多个COM+组件有关,或者代码正在调用一些长时间运行的数据库存储过程。无论哪种情况,我认为Thread.sleep之所以有效是因为它给了可疑的组件足够的时间来完成其操作,然后再开始下一个操作。
如果这个理论是正确的,那么它表明操作之间存在某种交互,当Thread.Sleep给予足够大的值以允许操作完成时,就不存在交互问题。这也表明,也许其中一个COM+组件正在异步地执行某些操作。解决方法可能是在COM+组件代码中使用锁或关键部分。另一个想法是重新设计引起问题的代码部分,以允许同时进行多个操作。
因此,你遇到的问题可能不是由你正在查看的C#代码中的多个线程引起的,而可能是由长时间运行的操作引起的,如果在开始下一个操作之前没有给予足够的时间来完成,则有时会失败。这可能与C#代码中的多个线程无关。

你说得对 - 这是我正在努力做的事情之一。这个应用程序非常庞大且不简洁,所以显然需要很长时间来完成。 - AngelicCore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接