定时器延迟挂起应用程序

本文关键字:应用程序 挂起 延迟 定时器 | 更新日期: 2023-09-27 18:05:39

我有一个问题与system . timer . timer对象。我使用timer对象定期执行任务。在计时器构造函数中,我调用执行工作的方法(DoTimeCheck()),以确保任务在启动时也运行一次。工作(定期)在BackgroundWorker中完成。

我这样调用定时器:

 UpdaterTimer ut = UpdaterTimer.UpdaterTimerInstance;

我的问题是我需要延迟任务的第一次运行3分钟(在应用程序启动时运行的任务)。后续运行(经过的事件)应该无延迟地运行。我想通过调用

来实现这一点
System.Threading.Thread.Sleep(TimeToDelayFirstRunInMiliseconds);

,但这失败了,因为它也挂起了应用程序的UI(主线程),使其无法使用。我怎么能延迟DoTimeCheck()的第一次运行而不挂UI?计时器的代码如下。如果问题没有以清晰的方式呈现,请让我知道,我会编辑。提前谢谢你。

  public sealed class UpdaterTimer : Timer
{
    private static readonly UpdaterTimer _timer = new UpdaterTimer();
    public static UpdaterTimer UpdaterTimerInstance
    {
        get { return _timer; }
    }
    static UpdaterTimer()
    {
        _timer.AutoReset = true;
        _timer.Interval = Utils.TimeBetweenChecksInMiliseconds;
        _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
        _timer.Start();
        DoTimeCheck();
    }
    static void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        DoTimeCheck();
    }
    private static void DoTimeCheck()
    {
        //... work here 
    }
}

定时器延迟挂起应用程序

这样做的一种方法是给Timer Interval一个初始值(例如3分钟)。然后,在Elapsed事件处理程序中,您可以将间隔更改为将从此使用的常规值。

 _timer.Interval = Utils.InitialCheckInterval;
 static void _timer_Elapsed(object sender, ElapsedEventArgs e)
 {
     if (_timer.Interval == Utils.InitialCheckInterval)
     {
         _timer.Interval = Utils.RegularCheckInterval;
     }
     DoTimeCheck();
 }

看起来(尽管您没有显示代码),您正在主/GUI线程上调用Sleep(TimeToDelayFirstRunInMiliseconds);,所以这就是导致您的UI线程挂起的原因。相反,您应该在第一次运行时将计时器设置为延迟3分钟,然后一旦它运行,您将再次更改计时器,使其以您希望的频率运行所有后续运行。

你的UI驻留在同一个线程上,所以当你让线程进入睡眠状态时,它也会导致你的UI挂起。您需要在另一个线程上运行计时器。

您似乎已经在使用计时器了。在你启动另一个计时器之前,用另一个计时器延迟三分钟。

timer = new Timer();
timer.AutoReset = false;
timer.Interval = 3*60*1000;
timer.Elapsed += startOtherTimerMethod;
timer.Start();

编辑:我应该注意到,这与Peter Kelly的答案非常相似,除了他的解决方案更优雅,因为它只使用一个计时器,没有额外的方法,并利用了计时器在运行之间可变的事实。如果你喜欢这个答案,你也会喜欢他的。: -)

你的UI需要一个单独的线程,目前你也在休眠UI。

你不应该使用线程。在这种情况下,你应该使用winforms控件

BackgroundWorker,它从不锁定主UI。你可以在那里写你的逻辑。

的例子:http://www.knowdotnet.com/articles/backgroundworker.html

使用System.Threading.Timer -构造函数接受第一次运行的延迟参数和后续运行的间隔。