定时器延迟挂起应用程序
本文关键字:应用程序 挂起 延迟 定时器 | 更新日期: 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
-构造函数接受第一次运行的延迟参数和后续运行的间隔。