C# 通过定时器提升函数

C# 通过定时器提升函数,c#,.net,timer,C#,.net,Timer,我想定期提出一个函数。 当我完成一个功能循环,等待一段时间,只有他们开始第二次运行 我想这样做: timer = new System.Timers.Timer(); timer.Interval = 1000; timer.Enabled = true; timer.Start(); timer.Elapsed += TimerTick; private void TimerTick(object sender

我想定期提出一个函数。 当我完成一个功能循环,等待一段时间,只有他们开始第二次运行

我想这样做:

        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时的每一秒


如何解决此问题?

您可以在处理之前停止计时器,然后在处理完成后再次启动计时器:

private void TimerTick(object sender, EventArgs e)
{
    timer.Stop();

//My functionality

    timer.Start();
}
在最后一节中,将功能放在try catch和call 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;
}

您将发现,在代码完成后,计时器现在将运行1000毫秒。您还可以使用
timer.Stop()
timer.Start()

您可以随时执行以下操作:

while (true)
{
    // your functions
    Thread.Sleep(1000)
}

你必须找到一种方法通过外部机制来阻止这种情况,但它应该能工作。

你是对的:计时器将每秒运行一次:它不在乎你在计时器里做什么

您可以做的是在输入TimerTick方法时停止计时器

private void TimerTick(object sender, EventArgs e)
{
  timer.Stop();   
  //My functionality
  timer.Start();
}
您可以使用以下线程:

var thread = new Thread(o => {
    while(true)
    {
        DoTick();
        Thread.Sleep(1000);
    }
});
试试这个:

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;
}
使用此选项,表单(主线程)不会被锁定,您/用户可以随心所欲。

试试看

private void TimerTick(object sender, EventArgs e)
{
    timer.Stop();
    // My Functionality
    timer.Stop();
}
然而,你可能会被解雇。根据:

引发已用事件的信号始终排队等待在线程池线程上执行,因此事件处理方法可能在一个线程上运行,而对Stop方法的调用可能在另一个线程上运行。这可能导致调用Stop方法后引发已用事件。下一节中的代码示例显示了解决此竞争条件的一种方法


你可能想考虑<代码>线程>(代码)>而不是

问题是计时器的异步性质:如果你的方法在10秒内执行,那么你将得到每秒调用它。尝试现在检查你的方法是否正在运行,然后退出该方法,这样你将更同步地执行它。theRead。睡眠会阻塞你的线程,我不建议这样做。线程后的代码。睡眠将不会运行,直到1000毫秒过去,并且您的应用程序将显示为被阻止。警告:由于计时器抑制已过去事件中的所有异常,此代码的行为可能与计时器不同,因为DoTick()中的异常将终止调用线程。@Abel。。。为此,循环被封装到一个单独的线程中。