睡/等了很长时间

本文关键字:长时间 | 更新日期: 2023-09-27 18:00:14

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

在psuedo代码中,我试图做的是这样的:-

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

我在一个独立于主控制台或GUI程序的线程中有这段代码,并且必须按程序运行

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

任何信息都会有所帮助。

睡/等了很长时间

您应该使用Quartz。NET,它是一个可靠且非常准确的调度器。点击此处阅读更多信息:https://www.quartz-scheduler.net/

另一种方法是使用定时器

例如,每隔x分钟调用一次上的方法

注意:在这种情况下-在开始新操作之前,必须确保上一个操作已经完成。

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等。

好吧-如果你想坚持"while (true)"模式,你能做的是这样的smth:

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