Reputation: 125
I'm having issues creating a timer that when started will first sleep for 2 minutes. It will run for 5 minutes total and every minute will do work. This is what I have:
class Program{
static System.Timers.Timer aTimer;
static System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
static TimeSpan LongToRun = new TimeSpan(0,300,0)); //run for 5 minutes
static void Main (string[] args){
Thread.Sleep(120000); //sleep for 2 mins
sw.Reset();
sw.Start();
Start();
}
static void Start()
{
aTimer = new System.Timers.Timer();
aTimer.Interval = 60000; //every min
aTimer.Enabled = true;
aTimer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
aTimer.Start();
}
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
TimeSpan ts = sw.Elapsed;
if (ts.TotalSeconds >= LongToRun.TotalSeconds)
{
aTimer.Stop();
return;
}
DoWork();
}
}
timer_Elapsed never is called... Am I going about this wrong?
Upvotes: 0
Views: 1487
Reputation: 30464
Your Start procedure returns immediately after it started the timer and returns to your main program. The main program ends and the timer that was still running is finalized before it elapses.
Solution: make sure your program is running long enough for your timer to elapse.
Another problem is that you subscribe to the event after you started your timer. This is probably not a cause of the problem, but neat code would be to subscribe before you start the timer.
By the way, the timer class implements IDisposable. This means that the designer of this class informs you he uses scarce resources that need to be freed as soon as possible. Consider Disposing the Timer class as soon as it is not needed anymore. The using (...) statement is ideal for this.
Using async-await would make your code much easier to read and to maintain.
Consider the following code:
public static void Main()
{
Thread.Sleep(TimeSpan.FromMinutes(2));
var myTask = Task.Run( () => WorkerTask())
Task.Wait(myTask);
}
private static TimeSpan longToRun = new TimeSpan.FromMinutes(5);
// easier to read than new TimeSpan(0,300,0));
public static async Task WorkerTask()
{
StopTime = DateTime.Now + longToRun;
// repeatedly wait a while and DoWork():
while (DateTime.Now < StopTime)
{
await Task.Delay(TimeSpan.FromMinutes(2);
DoWork();
}
}
That's all, No need for ManualResetEvents, no Stopwatches, no Timers nor timer_elapsed event handlers.
It is even quite easy to pass parameters to procedure WorkerTask(), and cancelling the event for instance because the operator presses < esc > is easy if you create a CancellationTokenSource and pass a CancellationToken to the WorkerTask as a parameter. In fact, that would make the code even more simpler:
public static void Main()
{
Thread.Sleep(TimeSpan.FromMinutes(2));
using (var tokenSource = new CancellationTokenSource())
{
var myTask = Task.Run( () => WorkerTask(tokenSource.Token))
tokenSource.CancelAfter(TimerSpan.FromMinutes(5));
// instead of LongToRun
Task.Wait(myTask);
}
}
public static async Task WorkerTask(CancellationToken token)
{
// repeatedly wait a while and DoWork():
while (!token.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromMinutes(2, token);
DoWork();
}
}
More information:
Upvotes: 1
Reputation: 588
First of all, you've set incorrect period:
static TimeSpan LongToRun = new TimeSpan(0,**5**,0)); //run for 5 minutes
timer_Elapsed is never called because your application is closed earlier. Add Console.ReadLine() at the end.
static void Main (string[] args){
Thread.Sleep(120000); //sleep for 2 mins
sw.Reset();
sw.Start();
Start();
Console.ReadLine();
}
Upvotes: 0
Reputation: 1
As Sergey pointed out there is a mistake in the time period set in Timespan LongToRun. I have tried a cod with just Thread.sleep function. Hope the code is helpful for you.
class Program {
static System.Timers.Timer aTimer;
static System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
static TimeSpan LongToRun = new TimeSpan(0,5,0); //run for 5 minutes
static void Main (string[] args) {
Console.WriteLine("Start Of Program" + DateTime.Now);
Thread.Sleep(120000); //sleep for 2 mins
sw.Reset();
sw.Start();
Start();
}
static void Start() {
TimeSpan ts = sw.Elapsed;
while (ts.TotalSeconds < LongToRun.TotalSeconds) {
doWork();
Thread.Sleep(60000);
ts = sw.Elapsed;
}
Console.WriteLine("End of program");
Console.ReadLine();
}
static void doWork() {
Console.WriteLine(DateTime.Now);
}
}
Upvotes: 0