通过计时器引发函数

本文关键字:函数 计时器 | 更新日期: 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()代替