C#定时器中this.begininvoke执行刷新主界面时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#定时器中this.begininvoke执行刷新主界面时相关的知识,希望对你有一定的参考价值。

我想问下定时器里面10S延迟,定时器里面,this.begininvoke有6到7个代码,我想问下调用this.begininvoke,子线程切换到主线程,会不会耗费时间比较多

参考技术A 这没太看明白,但是this.begininvoke是异步委托,不会耗费太多资源,也不会耗费时间太多

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

【中文标题】如何停止在 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#定时器中this.begininvoke执行刷新主界面时的主要内容,如果未能解决你的问题,请参考以下文章

Invoke,BeginInvoke,EndInvoke

C#定时执行

C#中定时器执行定时器触发任务是单线程还是多线程?

C# 定时自动执行程序

C# 如何间隔一定的时间执行一次代码?

C# 三个定时器区别