C# 避免定时器重入的4种方法

System.Timers.Timer执行方法的时候,会开一个线程去执行,如果使用锁(方法3)避免重入,可能会有多个线程等在那里执行。

按照单片机的写法要推荐方法1

但是C#提供了方便的定时器Stop方法,所以可用方法2,但是这种方法有个弊端,就是如果要停止定时器的时候,如果有线程在执行,又会把定时器打开,所以还是推荐方法1吧。

  1. 使用标志位:设置一个标志位来跟踪定时器是否已经在执行。在定时器的回调函数中,首先检查这个标志位。如果标志位表示定时器已经在执行,则立即退出,避免重入。
private bool isTimerRunning = false;  
  
private void Timer_Elapsed(object sender, ElapsedEventArgs e)  
{  
    if (isTimerRunning) return;  
    isTimerRunning = true;  
  
    try  
    {  
        // 定时器的逻辑代码  
    }  
    finally  
    {  
        isTimerRunning = false;  
    }  
}
  1. 停止定时器:在定时器的回调函数开始时停止定时器,并在函数结束时重新启动它。这样可以确保在函数执行期间不会触发另一个回调。
private void Timer_Elapsed(object sender, ElapsedEventArgs e)  
{  
    timer.Stop();  
  
    try  
    {  
        // 定时器的逻辑代码  
    }  
    finally  
    {  
        timer.Start();  
    }  
}
  1. 使用锁:使用lock语句或Mutex来同步访问定时器回调函数中的代码。这可以确保即使多个线程同时进入回调函数,也只有一个线程可以执行其中的代码。
private object timerLock = new object();  
  
private void Timer_Elapsed(object sender, ElapsedEventArgs e)  
{  
    lock (timerLock)  
    {  
        // 定时器的逻辑代码  
    }  
}
  1. AutoReset属性:System.Timers.Timer类有一个AutoReset属性,当设置为false时,定时器在触发一次Elapsed事件后不会自动重置,需要手动重启定时器。这可以防止定时器在上一个回调还未完成时再次触发
System.Timers.Timer timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.Elapsed += OnTimedEvent;
timer.Start();

private void OnTimedEvent(Object source, ElapsedEventArgs e)
{
    try  
    {  
        // 定时器的逻辑代码  
    }  
    finally  
    {  
        timer.Start();  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值