简体   繁体   English

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

[英]Is there a way to force the application to run as single threaded?

We have an old project that we are supporting and there is an issue that occurs most probably due to multi-threading. 我们有一个正在支持的旧项目,并且最有可能是由于多线程导致的问题出现。 The original implementer 'fixed' it by doing a Thread.sleep before executing the problematic section. 原始实现者通过在执行有问题的部分之前执行Thread.sleep来“修复”它。 The workaround works but as the section is inside a loop the thread.sleep adds multiple minutes to the time it takes for the section to finish. 解决方法是thread.sleep但由于该节位于循环中,因此thread.sleep使该节完成所需的时间增加了几分钟。

In the last month we have been we have been experimenting with lower values for the sleep but we wish to find the root cause. 在上个月,我们一直在尝试使用较低的睡眠值,但我们希望找到根本原因。 During our investigations we were doing lock on private objects wherever we felt like that would help. 在我们的调查过程中,我们会lock任何我们认为有帮助的私人对象。 We looked for anything that might be spawning additional threads - found none. 我们寻找可能产生其他线程的任何内容-没有找到。 No Thread.start and no ThreadPool usage. 没有Thread.start,也没有使用ThreadPool。 What is confusing us is that during debugging we find our main thread in the middle of about 8 other threads that we don't know who spawned them. 让我们感到困惑的是,在调试过程中,我们发现我们的主线程位于其他8个线程的中间,我们不知道是谁产生了它们。 These are background threads so first thought I had was the threadpool but as I mentioned no mention of it in the code. 这些是后台线程,因此我首先以为我是线程池,但是正如我在代码中没有提到的那样。

It is .net 2.0 so no Async s. 它是.net 2.0,因此没有Async This is just a part of the bigger application so it is a windows service but we run it as CMD to be able to debug it easily The main application itself is a windows forms desktop app. 这只是较大应用程序的一部分,因此它是Windows服务,但我们将其作为CMD运行,以便能够轻松对其进行调试。主要应用程序本身是Windows Forms桌面应用程序。 It also uses COM+ components if that is any help. 如果有帮助的话,它也使用COM +组件。

I've tried [STA] instead of [MTA] . 我尝试使用[STA]而不是[MTA] Also Locking as aforementioned. 也如上所述锁定。 MemoryBarrier s as well. 以及MemoryBarrier

We still get the issue. 我们仍然遇到问题。

The issue is basically corrupted datasets and nulls in objects where they shouldn't be. 问题本质上是数据集损坏,对象不应为空。 It happens in about once every 25-100 iterations so reproduction is not straight forward but we have devised a test specifically for this issue to try to reproduce it. 它大约每25-100次迭代发生一次,因此重现并非一帆风顺,但我们专门针对此问题设计了一个测试来尝试重现它。

All that is pointing us into the direction of thread issues. 所有这些都将我们引向了线程问题的方向。

Back to the original question - Who could possibly by spawning those additional threads and how do we prevent these threads for being created? 回到最初的问题-谁可能通过产生这些额外的线程来解决这些问题,以及如何防止创建这些线程?

在此处输入图片说明

Please note the threads marked with red - those are background threads and as far as we can see no mention of them in the code. 请注意标记为红色的线程-这些是后台线程,据我们所知在代码中没有提及它们。

The suspected thread in the screenshot is actively modifying the cols in the dataset . 屏幕截图中的可疑线程正在积极修改dataset的cols。 Problem is - the methods calling the SetColValueOnRow function that the thread is executing are typical and don't use any kind of threading. 问题是-线程正在执行的调用SetColValueOnRow函数的方法很典型,并且不使用任何类型的线程。

The CPU affinity for this application is set to 1 Core [part of the original work-around] 此应用程序的CPU关联性设置为1核心[原始替代方法的一部分]

Thanks 谢谢

Edit: The database is oracle 12c but the issues we face happen before writing to the database. 编辑:数据库是oracle 12c,但是我们面临的问题是在写入数据库之前发生的。 They usually happen in DataSets where a whole record or a few of its columns can be wiped once every few testing iterations 它们通常发生在DataSets中,每执行几次测试迭代,就可以擦除整个记录或其中的一些列

I think you need to investigate why Thread.sleep works. 我认为您需要研究Thread.sleep为什么起作用。 It does not sound like the code is by itself spawning additional threads, but you would have to go through the entire code base to find that out - including the COM+ components. 听起来好像代码本身并没有产生额外的线程,但是您必须遍历整个代码库才能找到答案-包括COM +组件。

So the first thing I would do is to start up the program in debug and just press the F10 key to step into the program. 因此,我要做的第一件事是在调试中启动程序,然后按F10键进入程序。 Then open up the threads debug window and see if you see about the same number of threads as given in your question. 然后打开线程调试窗口,看看是否看到与问题数量相同的线程数。 If you do, then those are simply threads from the thread pool and your issue is probably unrelated to the multiple threads. 如果这样做,那么这些只是线程池中的线程,您的问题可能与多个线程无关。

If you don't see the same number of threads, then try setting a breakpoint at various stages of the program and see if you can find where those threads are getting created. 如果看不到相同数量的线程,请尝试在程序的各个阶段设置一个断点,看看是否可以找到在哪里创建这些线程。 When you find where they are getting created, you can try adding some locking at that point. 找到它们的创建位置后,可以尝试在此时添加一些锁定。 But, your issue still might not be caused by multiple threads corrupting memory. 但是,您的问题仍然可能不是由多个线程破坏内存引起的。 You should investigate until you are convinced that the issue is due to multiple threads or something else. 您应该进行调查,直到确信该问题是由于多个线程或其他原因引起的。

I suspect that the issue might be related to one or more of the COM+ components or maybe the code is calling some long running database stored procedure. 我怀疑问题可能与一个或多个COM +组件有关,或者代码正在调用一些长时间运行的数据库存储过程。 In any case, I suspect the reason why Thread.sleep works is because it is giving the suspect component enough time to complete its operation before starting on the next operation. 无论如何,我怀疑Thread.sleep起作用的原因是因为它给了可疑组件足够的时间来完成其操作,然后再开始下一个操作。

If this theory is true, then it suggests that there is some interaction between operations and when Thread.Sleep is given a sufficiently large value to allow the operation to complete - there are no interaction issues. 如果这个理论是正确的,则表明操作之间存在某种相互作用,并且当Thread.Sleep被赋予足够大的值以允许操作完成时-没有相互作用问题。 This also suggests that perhaps one of the COM+ components is doing some things asynchronously. 这也表明,COM +组件之一可能正在异步执行某些操作。 The solution might be to use locks or critical sections inside the COM+ components code. 解决方案可能是在COM +组件代码中使用锁或关键部分。 Another idea is to redesign the section of code that is causing the problem to allow multiple operations simultaneously. 另一个想法是重新设计导致问题的代码部分,以允许同时进行多个操作。

So, the problem you are experiencing may not be due to multiple threads in the C# code you are looking at - but might be due to a long-running operation that will sometimes fail if not given sufficient time to complete before starting the next operation. 因此,您遇到的问题可能不是由于您正在查看的C#代码中有多个线程-可能是由于长时间运行的操作有时会失败,如果在启动下一个操作之前没有足够的时间完成操作,则有时会失败。 This may or may not be due to multiple threads in the C# code. 这可能是也可能不是由于C#代码中的多个线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM