I have a maze game. After you press Enter, you can enter a cheat code, also, the timer will pause. But after entering the code, my timer resumes but it decrements 3x each second. Here's the condition for pressing Enter:
// gt.setTimer() is called at the moment the maze started
// I'm using getch to trap inputs
else if (move == 13) //Reads if Enter is pressed
{
pause = 1; //A Flag saying that the timer must be paused
gt.setTimer(pause); //Calls my setTimer() method
Console.Write("Enter Cheat: ");
cheat = Console.ReadLine();
pause = 0; //A Flag saying that the timer should resume
gt.setTimer(lives, pause); //Calls again the Timer
}
Here's my setTimer() code:
static System.Timers.Timer t = new System.Timers.Timer();
static int gTime = 300;
public void setTimer(int pause)
{
t.Interval = 1000; // Writes the time after every 1 sec
if (pause == 1)
t.Stop(); // Stop the timer if you press Enter
else
t.Start(); // Starts the timer if not
t.Elapsed += new ElapsedEventHandler(showTimer);
}
public static void showTimer(object source, ElapsedEventArgs e)
{
Console.Write("Time " + gTime); //Writes time
gTime--; //Decrements the time
}
Is there something wrong? Am i missing something?
The problem is in the last line of the setTimer method. The timer handler should be registered just once after calling constructor, and not in the setTimer. On the elapsed timer event, the handler is called the number of times it has been registered. Thus the more you use operator += more times it being called.
Every time when you do:
t.Elapsed += new ElapsedEventHandler(showTimer);
you add one more event handler to this event
This strind runing only once, in par code where you initialise timer
Related
I use System.Timers.Timer to start a timer. There is an event that
is raised occasionally, every time this event raises I increment a counter.
If the counter > 3, I execute a method to perform an action and I need to repeatedly do this.
I reset the counter every N seconds to start counting the events again from 1.
When the counter resets to 0, I need to stop the ongoing action that gets triggered by the timer, but I can't get it to stop and this method keeps on executing even after the counter has reset to 0.
My program has this structure:
class Program
{
static void Main(string[] args)
{
var counter = 0;
//Create timer
var delayTimer = new System.Timers.Timer
{
// Interval = 900000, // every 15 minutes
Interval = 45000, // debug
AutoReset = true,
};
// Start the timer
delayTimer.Start();
delayTimer.Elapsed += ((o, e) =>
{
// when timer elapses reset the counter
counter = 0;
// stop the timed action function which was executing every N seconds for counter > 3
TimedTask(1, false, "stop"); // stop the timer
});
// an event raises the counter
while (event)
{
counter++; // keeps track of events raised
if (counter > 3)
{
// take a specific action
TimedTask(30000, true); // start the timer to perform an action every 30 seconds
}
}
// to keep the application going
System.Windows.Forms.Application.Run();
}
}
// method to start a timer for repeating a task every N seconds, or stop the counter for this ongoing timed task
public static void TimedTask(int interval, bool autoreset, string stop = null)
{
//Create timer
var delayTimer = new System.Timers.Timer
{
Interval = interval, // every N seconds
AutoReset = autoreset, // true: repeat, false: don't repeat
};
if (stop != null)
{
delayTimer.Elapsed += ((o, e) =>
{
// if 'stop' passed as string, stop executing the task every N seconds
delayTimer.Stop();
});
}
else
{
// Start the timer
delayTimer.Start();
// Create the event handler
delayTimer.Elapsed += ((o, e) =>
{
// when timer elapses call the method below
RepeatedAction();
});
}
}
// repeated action method
public static void RepeatedAction()
{
// perform an action, repeat it every N seconds
}
}
I have tried sending an additional string parameter "stop" to un-register the timer but this does not work.
I am creating two different timers: one for resetting the counter and one for repeating the timed task, could I minimise this by creating a timer method or something? Thanks in advance.
I have an application that calls static methods in a DLL every 60 seconds as part of a system "self-check" application. When I manually run the methods, they all complete in less than 10 seconds. My problem is the timer.elapsed event is firing twice, one right after the other. To add to that, for each time the timer elapses, the event fires one more time. (e.g. first time it's 2 firings, second it's 3, third it's 4, etc.) I have tried setting the timer.AutoReset = false along with setting timer.Enabled = false at the beginning of the elapsed event and then setting it to true at the end of the event. I've tried resetting the interval in the event. Every post I have found indicates that the above actions should have resolved this problem. Can anyone help me find what I'm missing?
static Timer cycle = new Timer();
static int cycCount = 0;
static void Main(string[] args)
{
Console.WriteLine("Firebird Survivor Auto Cycle Started.");
Console.CancelKeyPress += Console_CancelKeyPress;
cycle.Interval = 60000; //set interval for service checks.
cycle.Elapsed += new ElapsedEventHandler(CycleComplete_Elapsed);
cycle.AutoReset = false;
cycle.Enabled = true;
cycle.Elapsed += CycleComplete_Elapsed;
while (1 == 1) //stop main method from completing indefinitely
{
//WAIT FOR TIMER TO ELAPSE
}
}
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
cycle = null;
}
static void CycleComplete_Elapsed(object sender, ElapsedEventArgs e) //method triggered by timer
{
cycle.Enabled = false;
cycCount++;
WormholeServiceControls.CheckWormHoleStatus();
TimeControls.CheckTimePl(); //call time check
PegasusServiceControls.CheckPegasusStatus(null);
Console.Clear();
Console.WriteLine("--------------------------");
Console.WriteLine(String.Format("| Successful Cycles: {0} |", cycCount));
Console.WriteLine("--------------------------");
cycle.Enabled = true;
}
It seems your problem comes from the event handling you are doing. You are assigning the Elapsed event more than one time:
cycle.Elapsed += new ElapsedEventHandler(CycleComplete_Elapsed);
cycle.Elapsed += CycleComplete_Elapsed;
Why this two lines?. You will be all right with only this:
cycle.Elapsed += new ElapsedEventHandler(CycleComplete_Elapsed);
I'm trying to figure out how to make it so, after lets say, 1 minute so 60000 milliseconds the console will say hi.
All I have so far is
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Start();
But I don't know how to make it so when the timer is done, it will do something.
You can use the elapse event, when 60000 ms has pass the event will be thrown. Example of the elapse event:
class Program
{
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Elapsed += new System.Timers.ElapsedEventHandler(elapse); // subscribing to the elapse event
timer.Start(); // start Timer
Console.ReadLine(); // hold compiler until key pressed
}
private static void elapse(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hy");
}
}
or
void Main()
{
var t = new System.Threading.Timer((s)=>Console.WriteLine("Hi"),null,0,60000);
Console.ReadLine();
}
You can use System.Threading.Thread.Sleep if you only want to do the write once (the timer will run every x seconds):
System.Threading.Thread.Sleep(60000);
Console.WriteLine("something");
What you will want to do is create an event that writes to the console when the timer has elapsed the predefined amount of time.
This is done as follows:
Start by creating your timer and set it to 60s:
var timer = new System.Timers.Timer(60000); //60seconds
Next create an event that will be triggered when the time has elapsed:
private static void MyEvent(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello World");
}
Next, bind the timer to that event:
timer.Elapsed += MyEvent;
What this does is tell the computer that when the timer actually starts running in the future and then the timer elapses (60s passes after the timer starts), then the Event called 'MyEvent' will be called which writes to the console.
Finally Start the timer:
timer.Start();
And wait for the even to trigger and write to the console.
I have Form with a Timer1, and it set to 10Sec.
There is a KeyDown event - when the user press "Enter", I would like to save in "ans" the time duration that past in the 10S interval before it ends.
For Example: If i starting the timer1 now, and after 3Sec, I'm pressing Enter, ans = 3. and if I didnt press any key, ans will be equal to 10.
I have this code:
if (e.KeyCode == Keys.Enter)
{
ResponseTimeList.Add(timer1.Interval);
}
*ResponseTimeList is:
public List<double> ResponseTimeList = new List<double>();
How can i improve it?
Thanks.
Well, to start out with, Timer is not what you want to use. The timer class is designed to fire off events at a pre-defined interval of time; for example, you might use a timer to update a text box on a form every 10 seconds.
Instead, what you wish to do is use a stopwatch (System.Diagnostics.Stopwatch). Call Stopwatch.Start() whenever you want to start timing. When the user presses enter, simply call Stopwatch.Stop() and then get the time interval that has elapsed in seconds.
Finally, for the 10-second logic, you will need to use something like this (a conditional evaluation):
var timeToDisplay = Stopwatch.ElapsedMilliseconds > 10000 ? 10 : Stopwatch.ElapsedMilliseconds/1000
You can use Tick event of Timer.
bool isPressed = false;
Timer timer1 = new Timer() { Interval = 10000};
timer1.Tick += (s, e) =>
{
if (!isPressed)
ResponseTimeList.Add(timer1.Interval);
isPressed = false;
};
And when key pressed:
if (e.KeyCode == Keys.Enter)
{
ResponseTimeList.Add(timer1.Interval);
isPressed = true;
}
I have a windows service written in C# that executes a method correctly. I added a timer to schedule the method execution and it doesn't seem to fire the ElapsedEventHandler event.
System.Timers.Timer timer = new System.Timers.Timer();
public LabelService()
{
InitializeComponent();
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
public void SetTimer()
{
DateTime nextRunTime = GetNextRunTime();
var ts = nextRunTime - DateTime.Now;
timer.Interval = ts.TotalMilliseconds;
timer.AutoReset = false;
timer.Start();
}
void timer_Elapsed(object source, ElapsedEventArgs e)
{
// ** never gets here **
timer.Stop();
// run some code
SetTimer();
}
I can run and hit a breakpoint at timer.Start(); so I know that's being done, but it never falls into the timer_Elapsed method. (For testing I change ts.TotalMilliseconds to 1000) Any ideas?
"If Enabled is set to true and AutoReset is set to false, the Timer raises the Elapsed event only once, the first time the interval elapses. When Enabled is true and AutoReset is true, the Timer continues to raise the Elapsed event on the specified interval."
So I think you gotta set
timer.AutoReset = true;
I know this is old, but for anyone else with the same problem I was able to work around this by using;
public void StartTimer()
{
_timer.Interval = _pollingIntervalMilliseconds;
_timer.Enabled = true;
_timer.AutoReset = false; // We must manually restart the timer when we have finished processing
_timer.Elapsed += CheckForUpdates;
_timer.Start();
if (Environment.UserInteractive)
{
Console.WriteLine("System now running, press a key to Stop");
Console.ReadKey();
}
}
private void CheckForUpdates(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Checking For Update");
DoSomethingSlow();
_timer.Start(); // restarts the timer to hit this method again after the next interval
}
It will keep hitting the Elapsed Event until you hit a key to exit
From comments on the question you say you are calling it like this:
#if (!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new LabelLoader() };
ServiceBase.Run(ServicesToRun);
#else
LabelLoader ll = new LabelLoader();
ll.Start();
#endif
If you are in debug mode that means your main method is this:
LabelLoader ll = new LabelLoader();
ll.Start();
This means that once it has run these two lines the program finishes running and presumably exits. It doesn't matter what your timer is up to, the program has quit and thus your timer never fires.
I'd advise testing your ll with a better harness. Personally I use a winform type interface and just have a start button to mimic the service start (which will then have your code in the button click). Once I think I have that code running as I want I then test it in a service environment.