C# 保持方法运行的最佳方式是什么
我必须在24x7小时内一直运行一个方法 应用程序应该使用一些线程每秒处理40个数据。 我可以使用while或递归调用相同的方法。但在这两个过程中 cpu使用率过高,几乎达到95-100%。我不能用定时器,因为 然后处理线程工作不正常。根据提供的解决方案 很多人在睡觉的时候用线说话。但是如果我使用线程睡眠 然后它在每次迭代中都会得到延迟。我正在使用c#4.0 我的问题:有没有更好的解决方案来减少cpu的使用 主要方法是:C# 保持方法运行的最佳方式是什么,c#,c#-4.0,C#,C# 4.0,我必须在24x7小时内一直运行一个方法 应用程序应该使用一些线程每秒处理40个数据。 我可以使用while或递归调用相同的方法。但在这两个过程中 cpu使用率过高,几乎达到95-100%。我不能用定时器,因为 然后处理线程工作不正常。根据提供的解决方案 很多人在睡觉的时候用线说话。但是如果我使用线程睡眠 然后它在每次迭代中都会得到延迟。我正在使用c#4.0 我的问题:有没有更好的解决方案来减少cpu的使用 主要方法是: static void Main(string[] args) {
static void Main(string[] args)
{
while(true)
{
processData();
Thread.sleep(1000);
// here i use a 1 second sleep just for give a breath of CPU.
//But this one second sleep make me delay for enter data processing.
// I am looking for a better solution that no sleep time will use and CPU usages will getting low.
}
}
//Method should run always
static string processData()
{
{
// Open and close threads to process the data in every second.
}
// processData(); // it can be used for recursive method calling
}
但是如果我使用线程睡眠,那么每次迭代都会有延迟。我正在使用c#4.0
您可以使用,这表示:
该线程应该挂起以允许其他等待的线程执行
这将允许线程放弃一些处理给其他线程,防止它使用100%的CPU,但仍然允许它以接近全速运行
请注意,使用任何延迟都会降低总体CPU使用率,但会降低总吞吐量。最大化吞吐量的唯一方法是允许它不停地旋转,这当然会使CPU使用率非常高。static void Main(string[]args)
static void Main(string[] args)
{
while(true)
{
var beginTime = DateTime.Now;
processData();
var duration = DateTime.Now.Subtract( beginTime );
// if you want to run 40 times per second,
// you need to spend 1000/40 = 25ms per iteration
var sleepDuration = (int)(25 - duration.TotalMilliseconds);
if( 0 < sleepDuration )
{
Thread.sleep(sleepDuration);
}
}
}
{
while(true)
{
var beginTime=DateTime.Now;
processData();
var duration=DateTime.Now.Subtract(beginTime);
//如果你想每秒跑40次,
//每次迭代需要花费1000/40=25ms
var sleepDuration=(int)(25-duration.total毫秒);
如果(0<睡眠持续时间)
{
睡眠(睡眠持续时间);
}
}
}
编辑:如另一个答案中所建议的,如果您的
processData()
方法是线程安全的,则可以使用Timer
类,使用System.Threading.Timer可以告诉它下次执行的时间,例如:
System.Threading.Timer myTimer = new System.Threading.Timer(~~~)
在myTimer回调中:
myTimer.Change(nextRunTime, newInterval);
这将在下一个truntime运行代码,间隔将变为newInterval
有关“更改”方法的更多信息,请参见:
和在System.Threading.Timer上:
享受:)
抱歉,如果我是冒昧的,我的印象是,您不使用计时器的原因是因为总是有固定的延迟,但使用此方法,您可以在每次运行时调整延迟
不管怎么说,如果你遇到计时器处理不正确的问题,你能告诉我到底哪里出了问题吗?可能会对此有所帮助,并最终使用计时器或类似工具。在这种情况下,下面的代码可能是合适的解决方案。有关更多详细信息,请查看此项
但是如果我使用线程睡眠,那么每次迭代都会有延迟
-删除线程睡眠
??您处理的数据来自哪里?使用线程睡眠
没有错。也许你没有在最好的地方使用它?例如,如果您的代码不断循环并每秒执行10次,但您只需要每秒执行一次,那么在每次迭代之间只需休眠1秒。为什么1秒钟的延迟会引起问题?我已经编辑了你的标题。请看“”,其中的共识是“不,他们不应该”。在他当前的代码中,其他线程在1s睡眠期间不会继续工作吗?听起来他想让线程的1在重置之前完成它们的工作。谢谢你的评论。但是,这并不能减少我的CPU使用量。@riad您可以在任何时间内睡眠,并且它应该可以减少总使用量-如果系统上没有其他运行,使用0可能不会改变总使用量(但在这种情况下,使用100%的CPU不会有什么坏处)。如果不是这样,请尝试使用Thread.Sleep(1)
或Thread.Sleep(100)
来延迟较短的时间,而不是整整一秒钟…谢谢。你能推荐一些关于这个细节的文章吗?或者任何链接或帖子吗?你能推荐我使用GC.Collect()吗;在方法调用之后,性能会提高吗?比如:while(true){sendMT();GC.Collect();Thread.Sleep(0);}@RiadGC.Collect
可能会降低性能。这也是一个非常糟糕的主意,因为还有很多其他原因…他们有没有办法在不使用线程睡眠的情况下减少CPU的使用?基本上我不想运行这个方法40次。此processData将在完成其内部线程的字时运行。内线程每秒处理40个数据。我在这里没有提到。如果我使用线程睡眠,那么CPU的使用率在那一刻会变低。但是当代码进入线程块时,CPU的使用率又会变高。Timer
类会为您抽象出这一点,但任何未使用100%CPU的运行进程最终都会进入睡眠状态,我已经尝试在很多方面使用定时器。但是正确地执行我的代码是个问题。如何正确地打开和关闭线程以及许多其他问题。所以,我已经决定在这种情况下不使用计时器。非常感谢您的建议。但计时器并不是我的解决方案。好吧,如果我用这个答案浪费了你们的时间,我向你们道歉。我会看看我是否能找到其他想法,我已经玩了很多这种东西:)
myTimer.Change(nextRunTime, newInterval);
uint loops = 0;
while (true)
{
if (Environment.ProcessorCount == 1 || (++loops % 100) == 0)
{
processData();
Thread.Sleep(1);
}
else
{
processData();
Thread.SpinWait(20);
}
}