【问题标题】:C# or other: while loop to update inputs and process?C# 或其他:while 循环来更新输入和处理?
【发布时间】:2013-08-13 12:45:22
【问题描述】:

我正在开发一个监视/控制软件,基本上,它读取输入(通过网络模块)并在处理它们后生成事件。

虽然输入可以取决于通信速度,并且可以在多线程中运行,但处理基本上是一个连续循环,基本上:

while (true)
{
    readInputs();
    process();
}

这似乎很简单,但正如您想象的那样,cpu 将达到 100%。 如果您想运行其他循环,主要用于定时事件。 因此,虽然进程可以在最后休眠,但定时事件不能。

我的问题是:在不让应用占用整个 CPU 周期的情况下,收集和处理输入的最佳方式是什么?

更新 1: 该应用程序是多线程的,并具有用户界面。 计时器用于更新用户界面(来自共享内存 - 已处理的内容和输入状态)。 While 循环用于输入读取和处理。

【问题讨论】:

  • 您如何阅读您的输入? Console.ReadXXX 方法不会破坏 CPU..
  • @SimonWhitehead "读取输入(通过网络模块)" --> 不是控制台。
  • 傻我。不幸的是,我今晚的英语听不懂:(

标签: c# input while-loop


【解决方案1】:

在我看来,最好的方法是使用计时器并每秒调用这两个函数 - 如果需要,可以更频繁地调用,但这取决于它们做了多少工作。

例如:

System.Timers.Timer timer;

void SetupTimer()
{
    timer= new System.Timers.Timer();//create timer
    timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);//attach event handler
    timer.Interval = 1000;//set to fire every 1 second
    timer.Enabled = true;//starts the timer
}

void OnTimedEvent(object source, ElapsedEventArgs e)
{
    DoTasks();
}

void DoTasks()
{
    readInputs();
    process();    
}

您还可以添加一个isBusy 标志,以确保如果在下一个计时器超时事件发生时任务仍在处理中,那么它不会再次运行它们,当然这取决于您的确切需求。例如:

bool isBusy = false;
void DoTasks()
{
    if(isBusy)
        return;
    isBusy = true;
    readInputs();
    process();    
    isBusy = false;
}

【讨论】:

  • 定时器回调不是同步的吗?也就是说,如果仍在处理中,它就不会再次被调用。
  • @Ibasa:你可能是对的。我似乎记得类似的事情,但我不是 100% 确定
  • @Ibasa:在阅读了here 的“备注”部分后,还不是很清楚。我认为如果你以某种方式配置它,你可以同时拥有这两种方式,但我无法弄清楚它所说的哪一种是默认方式。它还建议在其中一种设置下使用标志来避免竞争条件
  • 默认 SynchronizingObject 为 null,因此回调不必是可重入的。 Stop 还有一个竞争条件,但这对于这个问题可能并不重要。
【解决方案2】:

虽然在这里不是一个坏主意,但您有两个问题。
1) CPU 最后
2) 可能是软件在读/写时挂起

要解决第一个问题,只需让当前线程休眠。

while (true)
{
    readInputs();
    Thread.Sleep(300); // more then 100
    process();
}

用SpinWait.SpinUntil读写解决第二个问题

我希望这会有所帮助。 问候

【讨论】:

  • 嗯......我认为这可能是采用模型的最佳选择。需要不断更新和处理。当您希望任务更准确时,无法为所有任务添加睡眠。
猜你喜欢
  • 1970-01-01
  • 2017-05-21
  • 2013-04-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 2017-06-15
相关资源
最近更新 更多