【问题标题】:waiting for x hours before executing a function using timer does not work在使用计时器执行功能之前等待 x 小时不起作用
【发布时间】:2015-06-17 16:58:27
【问题描述】:

我想在 C# 中执行一些代码之前等待 x 小时。我认为使用计时器是个好主意。 (使用 thread.sleep 似乎不正确)。但它只是行不通。我正在使用以下代码:

static void Main(string[] args)
{
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = x * 3600000;
    timer.Enabled = true;
    timer.Elapsed += (o, e) => SomeFunction(username);
    timer.AutoReset = true;
    timer.Start();
}

这段代码应该等待 x 小时然后执行 SomeFunction 但是当我调试它时,主函数在 timer.start() 之后结束。

你觉得这里有什么问题吗?或者你能建议除了 thread.sleep 或 await Task.Delay() 的替代方案吗?

【问题讨论】:

  • System.Timers.Timer 通常使用后台线程来引发事件,所以它会启动计时器然后继续前进,它不会阻塞。
  • 是的,我发现那里有问题。对 timer.Start() 的调用是异步的。这意味着在调用 timer.Start() 之后将继续执行。这会立即结束您的程序。您可以做的最明显的解决方案是在调用 timer.Start() 后以无限循环发送您的 main
  • “不起作用”是什么意思? (另外,我很好奇,这是您用于测试的值还是您尝试使用较低的间隔?)
  • 当然Main 退出 - 在timer.Start(); 之后没有代码。因此,如果您的应用程序无事可做,Thread.Sleep 并不比使用计时器更糟糕。也就是说,为此使用计时器(或Thread.Sleep)仍然不是一个好主意。为什么不使用例如windows任务计划程序代替?你到底想做什么?为什么要运行一个仅在启动数小时后才执行某些操作的应用程序?
  • 你甚至不需要计时器,记录开始时间,进入一个未绑定的循环,然后定期检查时差和睡眠。

标签: c# timer


【解决方案1】:

一旦您的Main 函数退出,您的进程以及包括计时器在内的所有后台线程都会结束。

您需要使用Thread.Sleep()Console.ReadKey() 或任何看起来合适的方式来保持主线程处于活动状态。

或者,如果您不想让您的进程保持活动状态,您可以register a scheduled task with Windows 在一小时后运行,然后结束。

【讨论】:

    【解决方案2】:

    这里有两个问题。第一个是当所有前台线程完成运行时可执行文件将退出。唯一的前台线程是经过Main(),所以它会退出。

    第二个是你没有在任何地方存储timer。即使另一个线程让可执行文件继续运行,timer 也可能在timer.Start() 返回后立即进行垃圾收集,当然在Main() 退出之后。

    使用 thread.sleep 似乎不对

    这通常不是一个好主意,但考虑到无论如何您只有一个线程,并且考虑到您必须在应用程序中至少有一个前台线程,Thread.Sleep 在这种特殊情况下似乎完全合理。 Task.Delay 一样多。

    更一般地说,我认为我更希望这是一项计划任务或一项服务。特别是,如果我想等待几个小时才能完成某件事,我经常希望它能够在重新启动后继续存在。

    【讨论】:

    • 不确定:定时器有资格进行垃圾收集我认为它在运行时会存在。想通过服务在重启后幸存下来的想法很好!
    • @TaW 肯定是这样。正是出于这个原因,定时器是GC.KeepAlive() 的一个非常常见的用途。 (请注意,GC.KeepAlive() 除了作为接受对象作为参数且不能内联的方法之外什么都不做,这足以防止收集,因为编译器在调用 KeepAlive() 之前不能重用堆栈空间) .
    【解决方案3】:

    查看 Quartz.Net 和 this 了解计划任务。

    【讨论】:

      猜你喜欢
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 2018-06-10
      • 2017-08-02
      相关资源
      最近更新 更多