3

我必须继续运行 24x7 的方法。基本上,应用程序应该每秒处理 40 个数据,通过使用一些线程。我可以使用 while 或递归调用 ling 相同的方法。但在这两个过程中,cpu 的使用率都太高了,几乎 95-100%。我不能使用计时器,因为那时处理线程无法正常工作。根据提供的解决方案,许多人谈论使用带有线程睡眠的while。但是如果我使用线程睡眠,那么每次迭代都会延迟。我正在使用 c# 4.0。

我的问题:有没有更好的解决方案来减少 CPU 的使用?

主要方法:

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
}
4

4 回答 4

7

但是如果我使用线程睡眠,那么每次迭代都会延迟。我正在使用 c# 4.0。

您可以使用Thread.Sleep(0),这表示:

应该暂停该线程以允许其他等待线程执行。

static void Main(string[] args)
{
  while(true)
  {
    processData();
    Thread.sleep(0);
  }
}

这将允许线程放弃一些处理给其他线程,防止它使用 100% 的 CPU,但仍然允许它以几乎全速运行。

请注意,使用任何延迟虽然会降低整体 CPU 使用率,但会降低吞吐量。最大化吞吐量的唯一方法是让它不停地旋转,这当然会使 CPU 使用率保持在非常高的水平。

于 2013-10-08T19:52:10.807 回答
0
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);
        }
    }
 }

编辑:正如另一个答案中所建议的,如果您的方法是线程安全的,您可以使用Timer该类processData()

于 2013-10-08T19:56:01.087 回答
0

使用 System.Threading.Timer 您可以告诉它下一次执行的时间,例如:

System.Threading.Timer myTimer = new System.Threading.Timer(~~~)

在 myTimer 回调中:

myTimer.Change(nextRunTime, newInterval);

这将在 nextRunTime 中运行代码,间隔将变为 newInterval。

有关此处提供的“更改”方法的更多信息:

http://msdn.microsoft.com/en-us/library/7hs7492w.aspx

在 System.Threading.Timer 上:

http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

享受 :)

抱歉,如果我是冒昧的,我的印象是你不会使用 Timer 的原因是因为总是有一个固定的延迟,但是使用这种方法你可以在每次运行时调整延迟。

无论如何,如果您遇到计时器无法正确处理的问题,您能分享那里到底出了什么问题吗?也许可以帮助解决这个问题,最后使用 Timer 或类似的东西。

于 2013-10-08T20:08:36.167 回答
0

在这种情况下,下面的代码可能是一个合适的解决方案。有关更多详细信息,请查看此链接

             uint loops = 0;
                while (true)
                {                    
                    if (Environment.ProcessorCount == 1 || (++loops % 100) == 0)
                    {
                        processData();
                        Thread.Sleep(1);

                    }
                    else
                    {
                        processData();
                        Thread.SpinWait(20);

                    }
                }
于 2013-10-09T10:10:29.783 回答