如何停止在 C# 类中运行的计时器

Posted

技术标签:

【中文标题】如何停止在 C# 类中运行的计时器【英文标题】:How to stop a timer running inside a class C# 【发布时间】:2015-09-23 14:07:23 【问题描述】:

我有一个在课堂上运行的计时器。我有两个按钮。 按钮 1 是启动计时器(在类内) 按钮 2 用于强制停止计时器。 单击按钮 1 并执行计算时,计时器运行平稳。 但是当我按下按钮 2 时,计时器不会强制停止并引发异常

发生了“System.NullReferenceException”类型的未处理异常“。

注意:如果我使用公共静态 System.Timers.Timer theTimer1;然后计时器可以用按钮 2 停止。但我不想使用静态,当条件为真时,它会自动停止,但停​​止方法不适用于按钮。 我怎样才能用按钮停止这个计时器。 谢谢。

public partial class Form1 : Form

    public Form1()
    
        InitializeComponent();             
     

    Test acc = new Test();

    private void button1_Click(object sender, EventArgs e) 
    
        acc.SerialPortEvent()
    

    private void button2_Click(object sender, EventArgs e) 
    
        acc.stop();
    


class Test

    public System.Timers.Timer theTimer1;

    public void SerialPortEvent()
    
        theTimer1 = new System.Timers.Timer(10000);
        theTimer1.Elapsed += timer_Tick;
        theTimer1.Start();
    

    void timer_Tick(object sender, EventArgs e)
    
        //Perform some calculations here.
        if (something like counter)
        
            stop();
        
    

    public void stop()
    
        theTimer1.Stop();
        theTimer1.Dispose();
    

【问题讨论】:

什么行号抛出异常? Timer1.Stop() 抛出异常; 【参考方案1】:

Test的构造函数中初始化定时器:

class Test

   public Test()
   
       theTimer1 = new System.Timers.Timer(10000);
   

您的代码仅在调用SerialPortEvent() 时才初始化计时器。

在您按下Start 按钮之前不会调用此方法,因此当您按下Stop 而不先按下Start 时会出现空引用异常。

此外,您的stop() 函数会配置计时器。当您尝试在释放计时器后停止计时器时,这可能是一个问题。

【讨论】:

谢谢@thumbmunkeys。我明白了。但我无法在按下按钮启动计时器后停止它。 您的代码是否在某个时候将计时器设置为null? (以stop() 为例) 我已经尝试过了,但它在 theTimer1.Stop(); 处引发异常。在丢弃之前。【参考方案2】:

您很可能正试图从一个不同的线程停止您的计时器

因此,假设您在线程 1 中,并且您创建了对在线程 2 中实例化的计时器的引用。一段时间后,线程 1 结束并且您处于线程 3 中,您试图从中获取该引用线程 1。这就是你得到空引用异常的原因。

您应该使用静态、易失或任务和任务取消令牌。

public volatile System.Timers.Timer theTimer1;

【讨论】:

我使用了静态,我可以按下按钮停止计时器。但我同时使用这个测试类进行另一个计算。因此,当我使用静态时,它会在两个位置由同一类产生一些问题。 使用任务和取消令牌,或者至少在你的定时器中添加一个“volatile”关键字——通过添加这个关键字,你可以让编译器知道你的字段可以从不同的线程访问。

以上是关于如何停止在 C# 类中运行的计时器的主要内容,如果未能解决你的问题,请参考以下文章

C# - 你如何停止计时器?

如何停止 System.Threading.Timer,然后更改其参数并再次运行? [复制]

如何使用倒数计时器停止游戏 - iOS [SWIFT] -

C# 为啥定时器会自动停止

外部类中的 NSTimer

C# winform中timer函数如何停止,点运行后可再次启动周期事件