Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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#_Multithreading_Entity Framework_Msmq_System.reactive - Fatal编程技术网

C# 为什么两个进程比两个线程有优势?

C# 为什么两个进程比两个线程有优势?,c#,multithreading,entity-framework,msmq,system.reactive,C#,Multithreading,Entity Framework,Msmq,System.reactive,我有一个基于MSMQ的定位应用程序,在该应用程序中,我接收来自现场单位的位置更新,并将其处理并放入数据库中 更新进程在DB之外没有依赖项,因此我可以使用可变数量的线程配置我的应用程序。由于我希望流程在出现故障时具有健壮性,因此我希望尽可能多地处理消息,但不要更多(因此,如果系统出现故障,我可以从我离开的地方开始处理) 我的应用程序工作正常,但我已经看到,如果我增加用于处理消息的线程数,我的平均消息数处于一个级别(我使用性能计数器来衡量这一点),我让系统利用,比如说,50%的可用CPU时间(我有一

我有一个基于MSMQ的定位应用程序,在该应用程序中,我接收来自现场单位的位置更新,并将其处理并放入数据库中

更新进程在DB之外没有依赖项,因此我可以使用可变数量的线程配置我的应用程序。由于我希望流程在出现故障时具有健壮性,因此我希望尽可能多地处理消息,但不要更多(因此,如果系统出现故障,我可以从我离开的地方开始处理)

我的应用程序工作正常,但我已经看到,如果我增加用于处理消息的线程数,我的平均消息数处于一个级别(我使用性能计数器来衡量这一点),我让系统利用,比如说,50%的可用CPU时间(我有一个内核i7 820QM,有4个物理内核和8个逻辑内核),但是,如果我不提升线程,而是启动相同数量的进程,那么我将使用100%的CPU时间,并获得更高数量的平均处理事件

这可能是一个锁争用问题吗?与Windows7处理超线程处理器的方式有关?我希望了解问题的本质,如果有任何建议,我将不胜感激


注意:我在这个项目中使用了MSMQ、Rx和实体框架。

没有看到您的代码,很难给出准确的答案,但我还是会添加一些可能性

首先,争用会产生巨大的影响,您使用的是什么锁定类型


其次,.NETFramework可能会产生影响,因为.NET2.0和早期的内核对象被用作锁定机制。这些需要的内核转换会改变影响性能的状态。

您是如何增加线程数的?问题几乎肯定与您使用Rx有关。我认为Rx坐标(读取需要一些锁)在某种程度上限制了你的线程,并不是所有的内核都能被利用。要想得到一个想法,请在你的应用程序中多次尝试,并检查调用堆栈在大多数情况下使用的方法。这会让你知道锁在哪里。@Wegged:newthread(()=>{…}{IsBackground=true}.Start();我现在看到,我使用的线程比我想象的要多。BeginReceive/EndReceive对从MessageQueue接收的每条消息都使用一个线程进行接收,我正在该线程中处理我的消息(不是我想象和想要的)。但事实上,加倍线程(与创建更多线程的线程无关)比加倍进程要慢。我想是争用,但我更想知道问题出在哪里。我的探查器运行时,将时间放在更新方法中,而不是放在框架中。我使用的是.Net4。我的锁定策略基本上是,没有由我管理的锁。我使用FromAsyncPattern和Begin接收来自MSMQ的消息Receive,EndReceive方法。每个线程都有它自己的这个可观察对象的副本,它指的是它自己的MessageQueue对象。基本上,我什么都不共享,所以我不接受锁,但仍然不能通过使用更多线程来提高利用率,但我可以通过使用进程来提高利用率。可能有一些东西是共享的,其中有锁,我看不到(可能是EntityFramework或SqlConnection?我将尝试禁用连接池!)。在我看到我的处理没有在正确的线程中完成之后,我改变了一些事情,并确保了这一点。随着我的线程数量的增加,报告的争用数量越来越高,使得这些线程难以继续。因为争用的源代码在库代码中(在我力所能及的范围之外),在这个场景中,我将转而使用进程而不是线程。谢谢!