【问题标题】:C# - Winform Timer - Disposing and emptying the timerC# - Winform Timer - 处理和清空计时器
【发布时间】:2019-10-21 12:02:22
【问题描述】:

对 C# 和计时器还很陌生,虽然我已经设法在 C# 中做了一些非常有趣的事情,但是我没有掌握 Timers 的窍门。

Form1.cs:

private int counter;
static System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
public void goTimer()
{
    // Set Counter
    counter = 60;

    // If timer is already enabled, stop it.
    if (timer1.Enabled)
    {
        timer1.Dispose();
        //timer1.Stop() <- also tried

    }

    timer1.Tick += new EventHandler(timer1_Tick);
    timer1.Interval = 1000; // 1 second
    timer1.Start(); // Timer exists

    txtCountdown.Text = counter.ToString();

}

private void timer1_Tick(object sender, EventArgs e)
{
    counter--;
    if(counter == 0)
    {
        timer1.Stop();
    }
    txtCountdown.Text = counter.ToString();
}

所以,发生的事情是它似乎按预期工作,直到您开始从例如调用 goTimer();按下一个按钮,它就会加速 (int) counter 的速度,就像你按下它的次数一样......一段时间后内存会被吃光。

在这种情况下,用户将能够调用定时器函数,因为它会删除一些对象,清除一些数据并刷新会话,而且当定时器达到 0 时。

使用 Winforms,我确实没有在 Visual Studio 中添加计时器(它仅在 Form1.cs 中引用)。

如何终止所有计时器,然后在 (int) counter 处重新启动?

【问题讨论】:

  • 定时器应该总是被处理掉,无论是否运行。 正确的地方是在表单的Dispose 方法中,而不是在启动计时器的方法中。
  • 在任何情况下该方法都不安全 - 它每次调用它都会修改计时器,添加越来越多的事件处理程序,而它唯一应该做的就是调用Start()

标签: c# winforms timer


【解决方案1】:

使用timer 的开始和停止是正确的方法,但通常 dispose 变体也可以工作。

您的内存漏洞是由多重事件处理程序分配造成的,您需要将此方法移至您的构造函数或其他一些初始化方法:

timer1.Tick += new EventHandler(timer1_Tick);

如果你真的想每次都创建一个新的定时器,你需要在之前释放事件处理函数:

timer1.Tick -= timer1_Tick;

【讨论】:

  • 定时器应该总是被释放,无论是否停止
  • c# if (timer1.Enabled) { timer1.Tick -= timer1_Tick; timer1.Dispose(); }
    似乎成功了!
  • @PanagiotisKanavos 你是对的,除非你想在提供的例子中重复使用它们
  • 它们仍然需要在表单关闭时进行处理。代码的问题在于它试图添加一个 new 事件处理程序,而不是仅仅启动或停止计时器。 goTimer() 应该只包含对 .Start() 的调用
【解决方案2】:

首先,正如 MichaelSander 已经提到的,您应该将这些行放在您的 Form1.cs 构造函数中:

timer1.Tick += new EventHandler(timer1_Tick); timer1.Interval = 1000; // 1 second

其次,如果要多次使用计时器,则处置计时器毫无意义。你应该使用timer1.Stop() 而不是timer1.Dispose(),就像在timer1_Tick 处理程序中一样。此外,检查计时器是启用还是禁用也没有意义,因为timer1.Start()timer1.Stop() 要么分别打开/关闭它,要么什么都不做。这意味着在您的情况下,您可以完全删除此块:

if (timer1.Enabled) { timer1.Dispose(); }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    相关资源
    最近更新 更多