通过计时器引发函数
本文关键字:函数 计时器 | 更新日期: 2023-09-27 18:09:15
我想定期引发一个函数。当我完成一个函数循环等待一段时间,只有他们开始第二次运行。
我想把它写成这样:
timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Enabled = true;
timer.Start();
timer.Elapsed += TimerTick;
private void TimerTick(object sender, EventArgs e)
{
//My functionality
}
但似乎TimerTick每秒钟被提出,而不是从我最后的TimerTick运行秒。
如何解决这个问题
你可以使用线程:
var thread = new Thread(o => {
while(true)
{
DoTick();
Thread.Sleep(1000);
}
});
你可以在做你的处理之前停止你的计时器,并在它完成后重新开始:
private void TimerTick(object sender, EventArgs e)
{
timer.Stop();
//My functionality
timer.Start();
}
将您的功能放在try-catch中并在finally部分调用Start()也是一个好主意。(如果适合的话)
尝试如下:
private void TimerTick(object sender, EventArgs e)
{
// get the timer that raised this event (you can have multiple
// timers, or the timer obj is out of scope here, so use this):
Timer timer = (Timer) sender;
// disable (or use timer.Stop())
timer.Enabled = false;
// ...
// your code
// ...
// at end, re-enable
timer.Enabled = true;
}
你会发现计时器现在将运行1000ms 后你的代码完成。您也可以使用timer.Stop()
和timer.Start()
你可以这样做:
while (true)
{
// your functions
Thread.Sleep(1000)
}
你必须找到一种方法来阻止这个通过外部机制,但它应该工作。
你是对的:计时器将每秒钟运行一次:它不会关心你在TimerTick中做什么。
你能做的是在进入TimerTick方法时停止计时器。
private void TimerTick(object sender, EventArgs e)
{
timer.Stop();
//My functionality
timer.Start();
}
试试这个:
DateTime lastDT = DateTime.MinValue;
private void TimerTick(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
if (now - last).TotalSeconds > what_you_want
{
//My functionality
}
last = now;
}
使用这个,你的表单(主线程)不会被锁定,你/用户可以做你想做的。
Try
private void TimerTick(object sender, EventArgs e)
{
timer.Stop();
// My Functionality
timer.Stop();
}
然而,你可能有一个额外的甚至解雇。根据MSDN文档:
触发Elapsed事件的信号总是在ThreadPool线程上排队等待执行,因此事件处理方法可能在一个线程上运行,而对Stop方法的调用可能在另一个线程上运行。这可能导致在调用Stop方法后引发Elapsed事件。下一节中的代码示例展示了一种绕过此竞争条件的方法。
你可以考虑用Thread.Sleep()
代替