Here's my problem: I have a timer that has an interval of 5 minutes. What I want is to be notified that there is only 30 seconds left on the timer so I can enable/disable certain controls (winforms in c#). I'm assuming that I would need 2 timers for this, maybe a new MyTimer class that would have these 2 timers as data members. The first timer would be for 5 minutes and the second be fore 4.5 minutes. The second timer would raise an event that I would listen to. Does anyone have any better ideas on this? Thanks for the help.
As Floris Velleman mentioned above, it would probably be best to use 1 timer that increments at a minimum time base, such as 30 seconds or even 1 second. Then use a counter and some condition statements that will react at certain times. Having 2 timers would require synchronizing between the two, which could cause some problems.
For example, with an interval of 1 second, you could do this:
int TimerInterval = 60 * 5; // 5 minutes
int NotifyTime = 30; // 30 seconds
int counter = 0;
// timer interval is set to 1 second
private void callback_MyTimer(object sender, EventArgs e)
{
counter--;
if (counter == NotifyTime)
{
// notify that 30 seconds are left...
}
// restart the counter for 5 minutes
if (counter <= 0)
{
counter = TimerInterval;
}
}
Waitable Timer objects, and the SetWaitableTimer function in particular, allow the due time and period to be controlled separately.
The MSDN documentation is here.
Related
So What I'm trying to do is basically.. Have 2 events, Lets called these Event 1 and Event 2, When Event 1 starts, a timer becomes activated, in which when it ends (the amount varies every time), It stores the elapsed time into a double variable
(Up to this stage it is all coded fine)
But my problem is.. I want Event 2 to run for half of the time that event 1 did.. And therefore I decided to store this value in another double variable, and setting the value divided by 2..
From here I'm wanting to then set up a sort of 'Countdown timer' So that once the amount of time has expired from the double variable with half the time stored, the event will stop.
Here is what I have so far..
//Creation of timer
Stopwatch Timer1 = new Stopwatch();
//Start the timer
Timer1.Start();
//Event 1 carries out here.. (Ain't going to bore you with this code)
//(Once ended) (ends once a condition is matched.. but cutting it short)..
//Timer1.Stop();
//Store amount in a double variable..
double dfull = Timer1.ElapsedMilliseconds;
//Half the amount in variable dhalf
double dhalf;
dhalf = dfull / 2;
//From here I want EVENT 2 to perform for the time stored in dC2B
You can do this using something like the following
System.Timers.Timer readyUpTimer = new System.Timers.Timer(100);
readyUpTimer.Elapsed -= readyUpTimer_Elapsed;
readyUpTimer.Elapsed += readyUpTimer_Elapsed;
DateTime readyUpInitialised = DateTime.Now;
readyUpTimer.Start();
Then in your event handler
void readyUpTimer_Elapsed(object sender, ElapsedEventArgs e)
{
TimeSpan elapsed = DateTime.Now - this.readyUpInitialised;
if (elapsed.TotalMilliseconds > dhalf)
{
readyUpTimer.Stop();
readyUpTimer.Dispose();
// Do other things...
}
}
I hope this helps.
I found this post and created a class that used it to detect inactive time and it works great. I set it for one minute and after one minute I can get it to "do stuff". What I am trying to do is only do something every "x" minutes of inactive time; i.e. every 5 minutes do this if things have been inactive and do not repeat again 'til X time has elapsed.
Now, I could set my timer to fire every 5 minutes instead of every second, but I would like to be able to "reset" the count of inactive time instead. Any suggestions?
This is for using the DispatchTimer in C# and WPF.
Just create a class level variable, increment it on your timer, and reset it when you get activity. Create a timer, say tmrDelay with an increment of 10000 milliseconds, and a button, btnActivity to reset the count, and do this:
private int tickCount = 0;
private const int tick_wait = 30;
private void tmrDelay_Tick(object sender, EventArgs e)
{
tickCount++;
if (tickCount > tick_wait)
{
DoSomething();
tickCount = 0;
}
}
private void btnActivity_Click(object sender, EventArgs e)
{
tickCount = 0;
}
It sounds like you want something like the following:
static DispatcherTimer dt = new DispatcherTimer();
static LastInput()
{
dt.Tick += dt_Tick;
}
static void dt_Tick(object sender, EventArgs e)
{
var timer = (DispatcherTimer)sender;
var timeSinceInput = TimeSpan.FromTicks(GetLastInputTime());
if (timeSinceInput < TimeSpan.FromMinutes(5))
{
timer.Interval = TimeSpan.FromMinutes(5) - timeSinceInput;
}
else
{
timer.Interval = TimeSpan.FromMinutes(5);
//Do stuff here
}
}
This will poll every 5 minutes to see if the system has been idle for 5 minutes or more. If it's been idle for less than 5 minutes it will adjust the time so that it will go off again at exactly the 5 minute mark. Obviously then if there has been activity since the timer was set it will be adjusted again so it will always aim for 5 minutes of idleness.
If you really want to reset the active time then you will actually need to trigger some activity either by moving the mouse or sending a keypress
I want the tick event to fire every hour exactly on completion of the hour. For e.g. it should tick on 8 am then on 9 am then on 10 am etc.
It's simple that I need to set the Interval to 3600000.
The problem here is how should I identify when should I start the timer?
I'm creating a tool which will run in system tray from the time when user will log on.
Please don't create a program that does nothing but waste memory. That's what Windows' Task Scheduler is for. Run your program every hour from such a task.
http://msdn.microsoft.com/en-us/library/aa384006%28v=VS.85%29.aspx
Here's a sample:
Go to Start->Programs->Accessories->Scheduled Tasks.
On the right side, click "Add Task..".
Select your executable.
Go to the Trigger tab.
Create Trigger with the following selection:
.
Run Daily
Start today at 8:00 am
Repeat every 1 Hour
I'm sorry that I can't provide any screenshots since I'm running the german version of Windows 7.
Maybe the following code is buggy, but the idea is like this:
public void InitTimer()
{
DateTime time = DateTime.Now;
int second = time.Second;
int minute = time.Minute;
if (second != 0)
{
minute = minute > 0 ? minute-- : 59;
}
if (minute == 0 && second == 0)
{
// DoAction: in this function also set your timer interval to 3600000
}
else
{
TimeSpan span = new TimeSpan(0, 60 - minute, 60 - second);
timer.Interval = (int) span.TotalMilliseconds - 100;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
}
void timer_Tick(object sender, EventArgs e)
{
timer.Interval = 3600000;
// DoAction
}
Per #smirkingman's suggestion, I removed 100 millisecond because of latency of project start-up and running time of the application:
timer.Interval = (int) span.TotalMilliseconds - 100;
I think it could be easier if you set up a timer every, let's say, minute, and this timer can check the system clock, when the desired time is less or equal than system time you can just run the actions (in this example with an error of 1 minute maximun)
You can improve it if you make the timer interval dinamyc, for example if you check the time and is still half an hour left you can set the interval for 15 minutes, nex time you reduce it to 5 minutoes and so on until you are checking the clock once a second, for examlpe.
HTH
Here's how I did this. The Tick event fires every 20 seconds. Simply change the minutes == "xxx" to whatever time you want the event to fire. If you need events spread out over hours, simply make the interval timer longer. Simple and effective.
private void timer1_Tick(object sender, EventArgs e)
{
DateTime Time = DateTime.Now;
int minutes = Time.Minute;
if (minutes == 00) //FIRE ON THE HOUR
{ DO THIS }
if (minutes == 15) //FIRE ON 1/4 HOUR
{ DO THIS }
if (minutes == 30) //FIRE ON 1/2 HOUR
{ DO THIS }
if (minutes == 45) //FIRE ON 3/4 HOUR
{ DO THIS }
}
Instead of firing the timer once an hour, maybe it would be more appropriate to fire the timer once a minute, and check to see if it's time yet.
The only problem with this is the worst case lag is 59 seconds. If you need it to fire exactly on the hour (at 10 am sharp), you may need to do some fiddling with the interval the first time so you line up.
There are three Timer classes that I am aware of, System.Threading.Timer, System.Timers.Timer, and System.Windows.Forms.Timer, but none of these have a .Reset() function which would reset the current elapsed time to 0.
Is there a BCL class that has this functionality? Is there a non-hack way of doing it? (I thought perhaps changing the time limit on it might reset it) Thought on how hard it would be to reimplement a Timer class that had this functionality, or how to do it reliably with one of the BCL classes?
I always do ...
myTimer.Stop();
myTimer.Start();
... is that a hack? :)
Per comment, on Threading.Timer, it's the Change method ...
dueTime Type: System.Int32 The
amount of time to delay before the
invoking the callback method specified
when the Timer was constructed, in
milliseconds. Specify
Timeout.Infinite to prevent the
timer from restarting. Specify zero
(0) to restart the timer immediately.
All the timers have the equivalent of Start() and Stop() methods, except System.Threading.Timer.
So an extension method such as...
public static void Reset(this Timer timer)
{
timer.Stop();
timer.Start();
}
...is one way to go about it.
For System.Timers.Timer, according to MSDN documentation, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx:
If the interval is set after the Timer has started, the count is
reset. For example, if you set the interval to 5 seconds and then set
the Enabled property to true, the count starts at the time Enabled is
set. If you reset the interval to 10 seconds when count is 3 seconds,
the Elapsed event is raised for the first time 13 seconds after
Enabled was set to true.
So,
const double TIMEOUT = 5000; // milliseconds
aTimer = new System.Timers.Timer(TIMEOUT);
aTimer.Start(); // timer start running
:
:
aTimer.Interval = TIMEOUT; // restart the timer
You could write an extension method called Reset(), which
calls Stop()-Start() for Timers.Timer and Forms.Timer
calls Change for Threading.Timer
I just assigned a new value to the timer:
mytimer.Change(10000, 0); // reset to 10 seconds
It works fine for me.
at the top of the code define the timer: System.Threading.Timer myTimer;
if (!active)
myTimer = new Timer(new TimerCallback(TimerProc));
myTimer.Change(10000, 0);
active = true;
private void TimerProc(object state)
{
// The state object is the Timer object.
var t = (Timer)state;
t.Dispose();
Console.WriteLine("The timer callback executes.");
active = false;
// Action to do when timer is back to zero
}
For a Timer (System.Windows.Forms.Timer).
The .Stop, then .Start methods worked as a reset.
You can do timer.Interval = timer.Interval
I do the following.
Disposing the timer and initializing it again.
But this will erase any event you attached to this timer.
timer.Dispose();
timer = new System.Timers.Timer();
Other alternative way to reset the windows.timer is using the counter, as follows:
int timerCtr = 0;
Timer mTimer;
private void ResetTimer() => timerCtr = 0;
private void mTimer_Tick()
{
timerCtr++;
// Perform task
}
So if you intend to repeat every 1 second, you can set the timer interval at 100ms, and test the counter to 10 cycles.
This is suitable if the timer should wait for some processes those may be ended at the different time span.
i do this
//Restart the timer
queueTimer.Enabled = true;
I need to run a function every 5 seconds for 10 minutes.
I use a timer to run it for 5 secs, but how do I limit the timer to only 10 mins?
Just capture the time that you want to stop and end your timer from within the elapsed handler. Here's an example (note: I used a System.Threading.Timer timer. Select the appropriate timer for what you are doing. For example, you might be after a System.Windows.Forms.Timer if you are writing in Winforms.)
public class MyClass
{
System.Threading.Timer Timer;
System.DateTime StopTime;
public void Run()
{
StopTime = System.DateTime.Now.AddMinutes(10);
Timer = new System.Threading.Timer(TimerCallback, null, 0, 5000);
}
private void TimerCallback(object state)
{
if(System.DateTime.Now >= StopTime)
{
Timer.Dispose();
return;
}
// Do your work...
}
}
Have your timer loop something like this:
DateTime endTime = DateTime.Now.AddMinutes(10);
while(endTime < DateTime.Now)
{
// Process loop
}
Divide the Y minutes by the X interval to get how many times it needs to run. After that you just need to count how many times the function has been called.
In your case, 10 min = 600 seconds / 5 seconds = 120 calls needed. Just have a counter keep track of how many times your function has been called.
Timer.Stop() after 120 Ticks.
just use a DateTime variable to track when it should end and set that right before you start. The on your Elapsed event handler, check if the signal time is less than the end time. If it isn't, stop the timer.
You can calculate how times your function will be call, and create decrement counter, after elapsed which you unsubscribe from timer tick. Or you can Run another timer which have tick period - 10 min and on tick you unsubscribe from timer tick calling your function.
Note the start time. In each call, test if currentTime + 5 seconds > startTime + 10 minutes. If so, disable the timer.
I prefer this approach to just running for N ticks, as timers are not guaranteed to fire when you'd like them to. It's possible 120 ticks may run over 10 minutes of real world time.
You can set two timers one that run for 5 secs and the other one that run for 10min and disable the first one
You could use a second timer:
class Program
{
static void Main(string[] args)
{
int interval = 5 * 1000; //milliseconds
int duration = 10 * 60 * 1000; //milliseconds
intervalTimer = new System.Timers.Timer(interval);
durationTimer = new System.Timers.Timer(duration);
intervalTimer.Elapsed += new System.Timers.ElapsedEventHandler(intervalTimer_Elapsed);
durationTimer.Elapsed += new System.Timers.ElapsedEventHandler(durationTimer_Elapsed);
intervalTimer.Start();
durationTimer.Start();
}
static void durationTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
intervalTimer.Stop();
durationTimer.Stop();
}
static void intervalTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//call your method
}
private static System.Timers.Timer intervalTimer;
private static System.Timers.Timer durationTimer;
}