Threading.Timer与Autoreset或单线程?

时间:2011-06-23 01:47:15

标签: c# multithreading timer

我想创建一个从GSM设备读取SMS消息的类。

我创建了一个定时器(system.threading),每秒读取一次传入消息。


public void ReadMessage(){
//read sms messages
//and store it into the database
}

有时ReadMessage()需要一秒钟以上。如何防止计时器 从前一个尚未完成时调用此过程?
1. AutoResetEventWaitOne对此有好处吗?
2. Threading.Timer是一个不错的选择吗?或者我应该在一个线程上进行吗?

3 个答案:

答案 0 :(得分:4)

您应该使用System.Timers.Timer,这样更容易使用 (这是Threading.Timer

的友好包装器

AutoReset设置为false,然后在处理程序的末尾再次Start()计时器。

不要使用专用线程;保持线程不做任何事都没有意义,这样你就可以每秒唤醒它。

答案 1 :(得分:3)

虽然这个问题很老,但您可以通过此代码激发灵感。它不使用任何其他线程,并且在执行代码期间不计算时间。

/// <summary>
/// Single thread timer class.
/// </summary>
public class SingleThreadTimer: IDisposable
{
    private readonly Timer timer;
    private readonly Action timerAction;

    /// <summary>
    /// Initializes a new instance of the <see cref="SingleThreadTimer"/> class.
    /// </summary>
    /// <param name="interval">The interval time.</param>
    /// <param name="timerAction">The timer action to execute.</param>
    /// <exception cref="System.ArgumentNullException">timerAction</exception>
    /// <exception cref="System.ArgumentException">interval</exception>
    public SingleThreadTimer(double interval, Action timerAction)
    {
        if (timerAction == null)
            throw new ArgumentNullException("timerAction");

        if (interval <= 0)
            throw new ArgumentException(string.Format("Invalid value '{0}' for parameter 'interval'.", interval), "interval");

        this.timerAction = timerAction;

        this.timer = new Timer(interval)
        {
            AutoReset = false
        };

        timer.Elapsed += timer_Elapsed;
        timer.Start();
    }

    public void Dispose()
    {
        if (timer != null)
            timer.Dispose();
    }

    private void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            timerAction();
        }
        finally
        {
            // Enable timer again to continue elapsing event.
            timer.Enabled = true;
        }
    }
}

答案 2 :(得分:1)

我根本看不到任何明确的计时器触发器。如果您解决此问题:

while(true){
  ReadMessage();
  Thread.Sleep(1000);
};

..这不完全符合你的要求,所有这些都很好地封装在一个线程中吗?

RGDS, 马丁