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?
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
精彩评论