开发者

Threading.Timer with Autoreset or Single Thread?

I want to create a class that reads SMS messages from a GSM device.

I created a timer(system.threading) that reads for incoming message every second.


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

Sometimes ReadMessage() takes more than a second. How can I prevent the timer from calling this procedure when the previous one is not yet finished?

1. Are AutoResetEvent and WaitOne g开发者_Go百科ood for this?

2. Is Threading.Timer a good choice? or should I do it on a single thread?


You should use a System.Timers.Timer, which is easier to work with.
(It's a friendlier wrapper around Threading.Timer)

Set AutoReset to false, then Start() the timer again at the end of the handler.

Don't use a dedicated thread; there's no point in keeping a thread around doing nothing so that you can wake it up every second.


Although this question is quite old, you can inspire by this code. It doesn't use any additional thread and it doesn't count time during execution of your code.

/// <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;
        }
    }
}


I cannot see any need for an explicit timer trigger at all. If you thread this off:

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

..does this not do exactly what you want, all nicely encapsulated in one thread?

Rgds, Martin

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜