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
Related
I have a WinForms program with a sign in system. On sign in, a class called session is created. This holds all information relevant to the sign in (much like the name "session" indicates).
Now I would like for this session to only have a limited duration. So after, lets say 30 minutes, the class destroys itself (or its parent does, that's not important).
How do I do this? I have tried searching Google, but apparently keywords like "Duration" and "Timespan" returns results which is in no way related to what I want to do.
You can use Interval timer tick with interval which start EventHandler every N seconds (you can start it once and do your job)
public class Form1 : Form
{
private Timer updateTimer;
public Form1()
{
updateTimer = new Timer();
updateTimer.Tick += new EventHandler(FixedUpdate);
updateTimer.Interval = 30000; //Time in miliseconds (30 seconds)
updateTimer.Start();
}
private void FixedUpdate(object sender, EventArgs e)
{
//Destroy your form first time it thicks after N time
}
}
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 on a small game, and I'm having trouble with some of the animations.
I want the Monsters to drop few pixels once every 3 seconds, so I added a condition for that that works. But the problem is the function that changes the Monster position, is getting called more then once, because the timer is still ticking when the condition is true.
This is the timer:
gameTimer = new System.Timers.Timer();
gameTimer.Elapsed += gameTick;
gameTimer.Interval = 10000/ 60;
gameTimer.Enabled = true;
The method gameTick:
private void gameTick(object sender, System.Timers.ElapsedEventArgs e)
{
theGame.Update(e.SignalTime.Second);
this.Invalidate();
}
the Update method that I call inside the gameTick method every 3 seconds:
public void Update(int secondsPassed)
{
if(secondsPassed % 3 == 0)
monsters.Update();
}
How can I make sure the method Update gets called only ONCE every 3 seconds?
It's like when it get to 3 seconds, the gate is opened to call the update method again until the condition turns false.
I'm not sure what can I add to the logic to stop it from running more the once.
Depending on your need you may want to capture current time at last update with DateTime.Now, add 3 seconds and call Update only when it passed:
DateTime nextUpdateTime = DateTime.UtcNow;
private void gameTick(object sender, System.Timers.ElapsedEventArgs e)
{
if (DateTime.UtcNow > nextUpdateTime)
{
nextUpdateTime = DateTime.UtcNow.AddSeconds(3);
theGame.Update(...);
}
....
Note that if you are planning to debug code you should avoid direct calls to DateTime.Now and figure out how you want time to move while waiting on breakpoint. Check out http://xboxforums.create.msdn.com/forums/p/53189/322422.aspx for discussion on time in games (XNA forum).
You should suspend the timer while gameTick is executing:
private void gameTick(object sender, System.Timers.ElapsedEventArgs e)
{
gameTimer.Enabled = false;
theGame.Update(e.SignalTime.Second);
this.Invalidate();
gameTimer.Enabled = true;
}
I have instantiated a timer like so:
System.Timers.Timer seconds = new System.Timers.Timer();
seconds.Elapsed += new ElapsedEventHandler(seconds_Tick);
seconds.Interval = 1;
seconds.Enabled = true; //start timer
I have created the tick event like so:
private void seconds_Tick(object sender, EventArgs e)//source
{
time++;
}//end clock_Tick()
time is an integer variable declared in the code.
I try to display the results like so (within a method):
txtProcessTime.Text = TimeSpan.FromSeconds(time).ToString();
This works great up until the timer runs longer than an hour so I then tried:
txtProcessTime.Text = TimeSpan.FromHours(time).ToString();
This shows an even more unusual/unexpected result.
I tried a few others but I reckon I'm using the wrong section..
I would like to code a timer that counts taking into consideration, milliseconds, seconds and hours and have the result displayed in a textbox. Can you help?
The timer is displayed in the format 00:00:00
The TimeSpan.FromHours issue displayed something along the lines of: 7070:xx:xx (I can't remember what the x's values were).
The TimeSpan.FromSeconds once the program has been running longer than an hour showed: 2:xx:xx (I can't remember what the x's values were).
The format is being displayed as mm:ss:milliseconds - Could it be that the minutes converted to single numbers once the 60 minutes has passed?
There is something apparently wrong here: Interval is specified in milliseconds, but you set it to 1. Then, you create the TimeSpan using FromSeconds.
So if you want an event every second, set it like this:
seconds.Interval = 1000;
If you still want it every millisecond, then change your TimeSpan:
txtProcessTime.Text = TimeSpan.FromMilliSeconds(time).ToString()
Instead of your current approach you may find this more usable, and easily modified for your requirements
using System.Diagnostics
Stopwatch sw;
public Form1()
{
InitializeComponent();
sw = new Stopwatch();
sw.Start();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = sw.Elapsed.ToString();
}
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;
}