【问题标题】:C# Pause Program ExecutionC#暂停程序执行
【发布时间】:2015-03-05 20:53:50
【问题描述】:

我正在编写一个每 10 或 15 分钟执行一次操作的程序。我希望它一直在运行,所以我需要一些处理能力便宜的东西。到目前为止,我所阅读的内容似乎表明我想使用计时器。这是我到目前为止的代码片段。

class Program {
    private static Timer timer = new Timer();

    static void Main(string[] args) {
        timer.Elapsed += new ElapsedEventHandler(DoSomething);
        while(true) {
            timer.Interval = TimerMilliseconds(); // The duration of the wait will differ each time
            timer.Enabled=true;
        }
    }
}

这里的问题是 while 循环一直在快速执行。如何在计时器结束之前暂停执行。我的程序真的不需要多线程。计时器是否适合这项工作?

提前感谢您的帮助!

更新:很抱歉造成混乱。我已经实现了 DoSomething 方法。我只是没有包括它,因为我不认为这是我的问题的一部分。

【问题讨论】:

  • 提示:删除你的while循环并实现DoSomething
  • 此外,您还可以考虑将您的应用程序设为Windows Service

标签: c#


【解决方案1】:

一旦指定的时间间隔过去,Timer 将触发 Elapsed 事件。

我会这样做:

private static Timer timer = new Timer();

static void Main(string[] args) 
{
    timer.Elapsed += new ElapsedEventHandler(DoSomething);
    timer.Interval = TimerMilliseconds(); // The duration of the wait will differ each time
    timer.Enabled=true;

    Console.ReadKey(); //Wait for keypress to terminate
}

您也可以将其实现为服务,这样您就不必像 Console.ReadKey 这样的阻塞调用来防止程序终止。

最后,您可以在事件处理程序中更改间隔:

static void DoSomething(...)
{
   timer.Stop();
   timer.Interval = TimerMilliseconds();

   ...
   timer.Start();
}

【讨论】:

  • 这看起来像我想要的。我正在使用 System.Timers.Timer。我需要手动停止计时器吗?如果没有设置 AutoReset 参数,我相信它会自动停止?
  • @Joe 你没有来停止它,但是如果进程运行时间很长,并且计时器间隔很短,你可以同时执行两个。这取决于你,没有它你可能会逃脱。
【解决方案2】:

此代码的问题在于您使用循环来设置TimerIntervalEnabled 属性,这将一遍又一遍地执行所述分配 - 它是不等待计时器以某种方式执行。

如果您的应用程序不需要多线程,那么您最好在两次执行之间调用Thread.Sleep

class Program {    
    static void Main(string[] args) {
        while(true) {
            Thread.sleep(TimerMilliseconds()); // The duration of the wait will differ each time
            DoSomething();
        }
    }
}

【讨论】:

  • 这是我想要的,但我认为使用 Thread.sleep 是不行的。
  • Thread.Sleep 这里可能没问题,但 Timer 还是更好
【解决方案3】:

从你的逻辑中取出计时器和循环。只需使用 Windows 调度程序在 15 分钟后执行您的程序。或者您可以使用 Windows 服务。请阅读Best Timer for using in a Windows service

【讨论】:

    【解决方案4】:

    完全删除while循环。

    DoSomething() 函数内部(一旦实现)在启动时停止计时器,并在结束时重置间隔,然后重新启动计时器。

    【讨论】:

      【解决方案5】:

      我猜 cmets 和 answrs 已经提供了您需要的提示,但 MSDN docs for Timer 实际上提供了一个很好的示例。在我看来,Timer 方法更简洁一些,更容易阅读您的意图并抽象出调用计划代码的细节。

      【讨论】:

        【解决方案6】:

        这是使用 ManualResetEvent 和 WaitOne() 的另一种替代方法。这将允许您停止主线程,而不必担心它被错误的按键意外杀死。您还可以在满足某些条件时 Set() MRE 以允许应用正常退出:

        class Program
        {
        
            private static Timer timer;
            private static ManualResetEvent mre = new ManualResetEvent(false);
        
            static void Main(string[] args)
            {
                timer = new Timer(TimerCallback, null, 0, (int)TimeSpan.FromMinutes(15).TotalMilliseconds);
                mre.WaitOne();
            }
        
            private static void TimerCallback(object state)
            {
                // ... do something in here ...
                Console.WriteLine("Something done at " + DateTime.Now.ToString());
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-11-10
          • 2010-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-09
          相关资源
          最近更新 更多