I have written a windows service that fetch some data from a database and perform some functions every minute. I have a timer setup in the initialize code segment.
public WindowsService()
{
InitializeComponent();
// Set up a timer that triggers every minute.
System.Timers.Timer timer1 = new System.Timers.Timer();
timer1.Interval = 60000; // 60 seconds
timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer1.Start();
}
private void OnTimer(object sender, EventArgs e)
{
//StartProcess();
}
After the deployment it worked without any issue. But when the date is changed to next day (eg:deployed on 29th June and the current date is 30th June), the scheduler is not performing. After I do a service restart manually, it performed as normal. What can be the issue with the timer?
I beleive your timer is getting garbage collected. Declare the timer variable outside of the function so it never goes out of scope.
Related
I'm developing an Web API (which works quite well). What's missing?
Here is sample code of Get Action:
public IEnumerable<xxxx> Get()
{
IEnumerable<xxxx> yyyy = new List<xxxx>();
//get yyyy from database
timer = new Timer();
timer.AutoReset = true;
timer.Enabled = true;
timer.Interval = 5000; //miliseconds
timer.Elapsed += timer_Elapsed;
timer.Start();
return yyyy;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//code to be executed when timer elapses...
}
So once a request is received, timer will be initialized and will fire Elapsed event at interval of 5 seconds. On next subsequent request this continues....
The expected behavior is such that:
Initialize Request -1
Initialize Timer -1
If another request from same client is received within 5 seconds, timer must not fire elapsed event.
If no request is received from same client within 5 seconds, timer should elapse and fire the event.
Also the timer has nothing to do with client(s).
Here is further business scenario related to this....
I'm developing a Web API that will be consumed by an electronic device when switched on. The device will keep sending it's ON status as long as the power is available. As soon as, user turns off the switch, the request to the server stops.
These status are updated into database whether device is ON or OFF. Now the trickier part was to identify when device turns off (complicated because the server does not know anything if the device stops sending any request). So for each devices there is a separate timer.
First of all, thank you #Patrick Hofman to guide me and think out of box...
I implemented a class having static property inside it.
public class DeviceContainer
{
public static List<DevTimer> timers=new List<DevTimer>();
}
public class DevTimer:Timer
{
public string Identifier {get; set;}
public bool IsInUse{get; set;}
}
and then in above code (in question), I made following changes:
public IEnumerable<xxxx> Get(string Id)
{
//Check if timer exists in
if(!DeviceContainer.timers.Any(s=>s.Identifier.Equals(Id)))
{
//Create new object of timer, assign identifier =Id,
//set interval and initialize it. add it to collection as
var timer = new DevTimer();
timer.AutoReset = true;
timer.Enabled = true;
timer.Interval = 5000; //miliseconds
timer.Elapsed += timer_Elapsed;
timer.IsInUse=true;
timer.Identifier=Id;
DeviceContainer.timers.Add(timer);
timer.Start();
}
else
{
//Code to stop the existing timer and start it again.
var _timer=DeviceContainer.timers.FirstOrDefault(s=>s.Identifier.Equals(Id))
as DevTimer;
_timer.Stop();
_timer.Start();
}
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//code that will turn off the device in DB
}
I'm not posting the entire code as that's not the purpose here.
I would use Microsoft's Reactive Framework for this.
Here's the code:
IEnumerable<xxxx> yyyy = new List<xxxx>();
Subject<Unit> clientRequestArrived = new Subject<Unit>();
IDisposable subscription =
clientRequestArrived
.Select(_ => Observable.Interval(TimeSpan.FromSeconds(5.0)))
.Switch()
.Subscribe(_ =>
{
//code to be executed when timer elapses...
//directly access `yyyy` here
});
All you need to do is call clientRequestArrived.OnNext(Unit.Default); every time that a user request comes in and that will be enough for this code to reset the timer.
If you want to stop the timer entirely, just call subscription.Dispose().
I have a windows form application with time input(in minutes) which fires a GUI application after the timer elapses. Initially I take the input from the user and set the time. Say, the user enters 45 mins. After 45 mins, my other GUI application is launched. Currently I'm using this:
Timer MyTimer = new Timer();
private void Form1_Load(object sender, EventArgs e)
{
MyTimer.Interval = 45mins // Input from user
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
//pop my GUI application
}
so now, my question is, how can i extended the timer? Suppose while counting down in the 20th Minute, the user wishes to extend 15mins of the timer, i take the input as 15 from the user and after that, the timer should add this 15 mins to the existing time and fire the GUI app after 35mins. i.e, it should count from 35mins.In total after the time elapses, it would have been 50mins. How can I achieve this?
Actually setting the timer to 1 second is just fine. there will be no performance hit. just keep track of the DateTime when it started, then you can use the tick event to display the elapsed time and check if that duration is greater than what the user wants
private DateTime timerStart;
private TimeSpan duration;
private void Form1_Load(object sender, EventArgs e)
{
Timer MyTimer = new Timer();
MyTimer.Interval = 1000; // tick at one second to update the UI
MyTimer.Tick += new EventHandler(MyTimer_Tick);
duration = whatever...// Input from user
timerStart = DateTime.Now;
MyTimer.Start();
}
private void changeTimer(TimeSpan newValue) {
duration = newValue;
}
private void MyTimer_Tick(object sender, EventArgs e)
{
TimeSpan alreadyElapsed = DateTime.Now.Subtract(timerStart);
// update the UI here using the alreadyElapsed TimeSpan
if(alreadyElapsed > duration)
{
//pop my GUI application
}
}
That's easy to implement if you set your timer to a one second/minute interval and another variable to the number of seconds/minutes.
Decrease the variable value on each timer tick. Add to that variable if you need to expand the interval. If the variable value is 0,launch the other application.
I'm working at a Windows Forms application and i need to use timers.
I have this method to set the timer in order to do something at a certain time:
private void SetTimerValue()
{
// trigger the event at 7 AM. For 7 PM use 19 i.e. 24 hour format
// Console.Read();
DateTime requiredTime = DateTime.Today.AddHours(7).AddMinutes(00);
if (DateTime.Now > requiredTime)
{
requiredTime = requiredTime.AddDays(1);
}
// initialize timer only, do not specify the start time or the interval
myTimer = new System.Threading.Timer(new TimerCallback(TimerAction));
// first parameter is the start time and the second parameter is the interval
// Timeout.Infinite means do not repeat the interval, only start the timer
myTimer.Change((int)(requiredTime - DateTime.Now).TotalMilliseconds, Timeout.Infinite);
}
And this is the TimerAction:
private void TimerAction(object e)
{
// do some work with my webcam(start recording)
// now, call the set timer method to reset its next call time
SetTimerValue();
}
I call SetTimerValue() in my Form (Form1):
public Form1()
{
InitializeComponent();
SetTimerValue();
}
But after I run the application and timer reaches his time, the application closes.
It's something with my TimerAction method and with the parameters (object e) ?
The same action of the TimerAction I have it in a button1_Click_1(object sender, EventArgs e) and it works.
Can you help me?
Thanks
You need to use the right timer, i.e. one that will be executed on the UI thread.
I want to show timer on UI such that when aplication star executing timer starts with 00:00:00 and when it completed its execution timer stops. Timer should show timing per second while running.
You can use the System.Windows.Forms.Timer, which is created for scenarios like yours. You can read more about in MSDN.
You should use the following code snippet as sample:
Timer timer = new Timer();
timer.Interval = 1000;
timer.Tick += new System.EventHandler(timer_Tick);
timer.Start();
private void timer_Tick(object sender, System.EventArgs e)
{
this.Text = string.Format("{0:hh:MM:ss}", DateTime.Now);
}
Notice that you should dispose the Timer when you do not needed.
I want to design changing time on maskedtextbox in my application like windows where time changes on every second. I have set maskedtexbox1 as below:
maskedTextBox1.Text = DateTime.Now.ToShortTimeString();
which is showing current system short time but it’s not changing on every second like windows. How to do?
I'm on Visual Studio 2005, and .NET is below 3.5.
I'd use the timer and fire an event every second to update the time.
Create a timer (an instance of class Timer in the package System.Windows.Forms).
Set its frequency to 1 second (i.e. 1000 milliseconds).
Tell it what method to call when it goes off (the event handler Kaboom).
Somewhere in your executable code you do that by typing the following.
Timer ticker= new Timer();
ticker.Interval = 1000;
ticker.Tick += new EventHandler(Kaboom);
In the same class (or, if you're confident how to do it, somewhere where you can reach the code) you also create the handler for the fired event of ticking, so that the promise you made about a method to be called when the timer goes off is kept.
private void Kaboom(Object sender, EventArgs eventArgs)
{
// Execute the tickability code
MaskedTextBox1.Text = DateTime.Now.ToShortTimeString();
}
Also, don't forget to actually start your ticker when you feel that you're ready.
MyTimer.Start();
Tada!
EDIT:
For the sake of completeness, I'm also going to paste in a part of the reply of #CuaonLe (a higher threshold of competence and requirement for .NET 3.5 or newer).
Timer timer = new Timer { Interval = 1000 };
timer.Tick += (obj, args)
=> MaskedTextBox1.Text = DateTime.Now.ToLongTimeString();
timer.Start();
I guess you'll need to setup a Timer which updates your maskedTextBox1 every second.
For how to do that, please see: Add timer to a Windows Forms application
Cheers. Keith.
You can use System.Windows.Forms.Timer to update textbox value every second for example:
var timer = new Timer();
timer.Interval = 1000;
timer.Tick += delegate
{
textBox1.Text = DateTime.Now.ToLongTimeString();
};
timer.Start();