睡觉/等待很长时间

时间:2015-06-28 11:01:09

标签: c# .net multithreading

我正在设计一个C#的工业硬件控制程序,该程序将通过串口连接运行72小时。

在psuedo-code中,我想要做的是这样的: -

while(true) {
    TalkToSerialPort1();
    WaitForXHours(3);
    TalkToSerialPort2();
    WaitForXHours(1);
    // etc
}

我将此代码放在与主控制台或GUI程序不同的线程中,并且必须以程序方式运行

似乎Thread.Sleep()很长一段时间似乎毁了我的一天!我正在寻找一种可靠的长时间睡眠方式。

任何信息都会有所帮助。

4 个答案:

答案 0 :(得分:2)

您应该使用Quartz .NET,它是可靠且非常准确的调度程序。 在此处阅读更多内容:https://www.quartz-scheduler.net/

答案 1 :(得分:1)

Stopwatch是解决这个问题的更好方法。例如:

    Stopwatch spw = new Stopwatch();            

    int stepNo = 0;
    while (!haltWork)
    {
        Thread.Sleep(100);
        switch (stepNo)
        {
            case 0:
                TalkToSerialPort1();
                spw.Restart();
                stepNo += 1;
                break;
            case 1:
                if (spw.Elapsed.Hours >= 3)
                {
                    TalkToSerialPort2();
                    spw.Restart();
                    stepNo += 1;
                }
                break;
            case 2:
                if (spw.Elapsed.Hours >= 1)
                {
                    TalkToSerialPort3();
                    spw.Restart();
                    stepNo += 1;
                }
                break;
            // etc...

        }
    }

这里我添加了一个条件haltWork - 如果有必要,你的主程序需要某种方式来通知这个线程及时退出。这将在轮询循环中运行线程,允许它断开并退出,支持用户取消,并且由于秒表,将为您提供用户取消时可用于当前步骤的精确时间过程诊断,重启程序等。

使用switch语句将程序过程分解为多个步骤。这使您可以以干净和逻辑的方式执行长时间运行的过程流程,同时保持响应,能够提供主动反馈(考虑定期引发事件以提醒当前步骤的主线程,时间已过去等,进程记录目的)。

另请注意,此示例会在每一步重置秒表 - 您如何执行此操作取决于您的要求;是否需要控制步骤之间的间隔,或者是否更重要的是保持相对于任意引用的正常速度。如果是后者,自然只需启动一次秒表,并使其余的间隔为绝对而非相对。

**我假设在C#应用程序中这样做已经仔细考虑,并且这是负责此任务的最佳位置。

Windows任务调度程序是处理重复"无头"需要长时间运行的任务。

另一种与工业控制特别相关的替代方案是使用专用硬件来实现这一目标 - 小型PLC等。

答案 2 :(得分:1)

替代方法是使用Timer

例如calling method on every x minutes

注意:在这种情况下 - 在开始新操作之前,您必须确保先前的操作已完成。

答案 3 :(得分:0)

好吧 - 如果你想坚持"while (true)"模式,  你可以做的就像这样:

while (true){

if (DateTime.Now - LastExecutionDate > 72h)
{
   doYourStuff();
   Update_LastExecutionDate;
}
else{
  continue; //or sleep for 5 minutes
}