如何在C#中重置计时器?


114

有三个Timer班,我知道的,System.Threading.TimerSystem.Timers.Timer,和System.Windows.Forms.Timer,但这些都没有一个.Reset()这将当前经过时间重置为0功能。

是否有具有此功能的BCL类?有没有一种非骇客的方式?(我认为可能更改其时限可能会重置它)思考重新实现Timer具有此功能的类有多困难,或者如何使用一个BCL类可靠地实现它?


3
使用JP解决方案时,使用扩展方法
benPearce

我也有相同的重置需求,并且出于相同的原因,FileSystemWatcher令人不愉快且使用不便
John Lewin 2009年

如果将Stopwatch用作计时器并使用扩展方法答案,请小心,因为.NET 4.0中提供了Stopwatch.Restart扩展方法。msdn.microsoft.com/en-us/library/…– 2009
si618

Answers:


148

我经常做 ...

myTimer.Stop();
myTimer.Start();

...那是黑客吗?:)

根据评论,在Threading.Timer上,它是Change方法 ...

dueTime类型:System.Int32调用构造Timer时指定的回调方法之前要延迟的时间,以毫秒为单位。指定 Timeout.Infinite以防止计时器重新启动。指定零(0)可立即重启计时器。


另一个问题是,只有Forms.Timer会引起问题,而我的应用程序没有GUI(没有参数的Application.Start()),因此我认为Threading.Timer类由于其他原因会更好,但是很不错。
马修·沙利

3
@Matthew:请参见msdn.microsoft.com/en-us/magazine/cc164015.aspx,以获取有关各种计时器类的讨论以及何时使用它们的适当方法。但是,通常Forms.Timer只应与GUI一起使用。但是,除了Forms.TimerThreading.Timer还有Timers.Timer
布赖恩2010年

60

除System.Threading.Timer外,所有计时器都具有等效于Start()和Stop()方法的计时器。

因此,扩展方法如...

public static void Reset(this Timer timer)
{
  timer.Stop();
  timer.Start();
}

...是解决问题的一种方法。


1
我不想测量经过的时间。我确切的用例是,我有一个FileSystemWatcher监视目录,并希望捕获更改组(例如,彼此之间在5秒内所做的更改)。从理论上讲,第一个更改会启动一个计时器,每次更改都会重置该计时器,直到最终触发并关闭该组为止。
马修·沙利

是的,当我重新阅读您的问题时,我发现了这一点。编辑了我的答案。
丹尼尔

这可行,需要注意的是,如果您仅打电话不能使用timer.Start()。我对此Linqpad查询进行了测试。尝试去掉timer.Stop它,您会发现区别。
Jared Beach

30

对于System.Timers.Timer,根据MSDN文档,http//msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx

如果在定时器启动后设置了间隔,则将重置计数。例如,如果将时间间隔设置为5秒,然后将Enabled属性设置为true,则计数在设置Enabled时开始。如果在计数为3秒时将时间间隔重置为10秒,则将Enabled设置为true后13秒内将首次引发Elapsed事件。

所以,

    const double TIMEOUT = 5000; // milliseconds

    aTimer = new System.Timers.Timer(TIMEOUT);
    aTimer.Start();     // timer start running

    :
    :

    aTimer.Interval = TIMEOUT;  // restart the timer

1
这里的问题是,您不总是希望在重置计时器的那一刻就知道计时器是否已经在运行。因此,您将必须执行aTimer.Interval = TIMEOUT和aTimer.Start()。因此,总的来说,上面的reset函数使用的行和变量更少。虽然很棒。
e-motiv 2014年

1
@ RU-Bn OP明确声明“ 一个.Reset()函数会将当前经过的时间重置为0。 ” -它没有提到它打算在设计不佳的应用程序上使用,而您甚至不知道计时器是否正在运行。还要检查作者的评论(超过4年前):“ 理论上,第一个更改会启动一个计时器,每次更改都会重置该计时器,直到最终触发并关闭组。 ” 无论如何,感谢您的不赞成投票。
mMontu 2014年

我也看到了这样的问题。我所做的是:aTimer.Interval = aTimer.Interval。这触发了循环的进行。击败了我为什么但它起作用了……
Herman Van Der Blom19年

7

您可以编写一个称为Reset()的扩展方法,该方法

  • 为Timers.Timer和Forms.Timer调用Stop()-Start()
  • 调用Change for Threading.Timer

5

我刚刚为计时器分配了一个新值:

mytimer.Change(10000, 0); // reset to 10 seconds

这对我来说可以。

在代码顶部定义计时器: System.Threading.Timer myTimer;

if (!active)
        {
            myTimer= new System.Threading.Timer(new TimerCallback(TimerProc));
        }
        myTimer.Change(10000, 0);
        active = true;

private void TimerProc(object state)
    {
        // The state object is the Timer object.
        System.Threading.Timer t = (System.Threading.Timer)state;
        t.Dispose();
        Console.WriteLine("The timer callback executes.");
        active = false;
        //action to do when timer is back to zero
    }

5

为了清楚起见,由于其他一些注释不正确,System.Timers将Enabled设置为true时重置经过的时间。我只是用以下方法测试了行为:

Timer countDown= new Timer(3000);

Main()
{
    TextBox.TextDidChange += TextBox_TextDidChange;
    countdown.Elapsed += CountDown_Elapsed;
}

void TextBox_TextDidChange(Object sender, EventArgs e)
{
    countdown.Enabled = true;
}

void CountDown_Elapsed(object sender, EventArgs e)
{
    System.Console.WriteLine("Elapsed");
}

我会在文本框中重复输入文本,并且计时器只会在最后一次按键后3秒钟运行。正如您将看到的,它也在文档中得到了提示:调用Timers.Start()仅将Enabled设置为true。

可以肯定的是,从一开始我应该直接讲到这一点,您将在.NET参考源中看到,如果启用一个已经启用的计时器,它将调用private UpdateTimer()方法,该方法在内部调用Change()


不你错了。UpdateTtimer当且仅当的当前值Enabled不等于new 时,才调用private 方法value
尼科洛·卡兰迪尼

3

对于计时器(System.Windows.Forms.Timer)。

.Stop,然后.Start方法用作重置。


1

重置windows.timer的其他替代方法是使用计数器,如下所示:

int tmrCtr = 0;
Timer mTimer;

private void ResetTimer()
{
  tmrCtr = 0;
}

private void mTimer_Tick()
{
  tmrCtr++;
  //perform task
}  

因此,如果您打算每隔1秒重复一次,则可以将计时器间隔设置为100ms,并将计数器测试为10个周期。

如果计时器应等待某些可能在不同时间段结束的进程,则此方法很合适。


1

我这样做

//Restart the timer
queueTimer.Enabled = true;

这就是启用它。即使预先禁用了它,重新启用也不会更改到该时间点为止已消耗的时间。
vapcguy

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.