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);
Related
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 simple Console application in C# that creates a timer to write text to the Console. Then it waits for the user to press a key.
If the user presses a key before five seconds elapse, then the application ends, and the timer never fires. If the user does not press a key, then the timer fires as expected.
Why does the thread that the timer creates not keep the application from terminating? How should I ensure that the application keeps running even if the user presses a key?
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(5000);
timer.Interval = 5000; // 5 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.AutoReset = true;
timer.Start();
Console.ReadKey();
}
public static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("Timer Fired.");
}
To get the timer message to always write out, you can have the main thread wait on a reset event that is signaled once the timer is fired.
static ManualResetEvent timerFired = new ManualResetEvent(false);
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(5000);
timer.Interval = 5000; // 5 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.AutoReset = true;
timer.Start();
Console.ReadKey();
// This call will return only after timerFired.Set() is
// called. So, if the user hits a key before the timer is
// fired, this will block for a little bit, until the timer fires.
// Otherwise, it will return immediately
timerFired.WaitOne();
}
public static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("Timer Fired.");
timerFired.Set();
}
As for the other question, why doesn't it prevent the application from exiting, I'll take a stab. The timer_Elapsed() is being called from a background thread. According to MSDN, background threads don't keep the execution environment running. There's a nice discussion here.
ThreadPool threads are background threads, and MSDN Timer documentation indicates that the Timer's Elapsed event is raised on a ThreadPool thread, so the application wouldn't wait for it as it's not a foreground thread.
I created windows service on C#.
For now I have methods for scanning DB.
I need call this method two times per minute. Actually I don't know method for waiting in windows service.
I tried Thread.Sleep... but nothing happened.
Please help me with this problem.
private int wait;
protected void Start()
{
wait = 1000;
while (true)
{
if (wait < 30000)
wait += wait;
//implement logic for waiting
Video video = new Video();
video.FindFileForConvert();
if (video.Path != null)
{
Console.WriteLine("video != null. video path = {0}", video.Path);
video.BeginConvertation();
video.DeleteOriginFile();
wait = 1000;
}
}
}
You should use System.Threading.Timer for the same. Since Thread.sleep is not a good practice atleast in some cases.
You may use Timer
public static int Main() {
/* Adds the event and the event handler for the method that will
process the timer event to the timer. */
myTimer.Tick += new EventHandler(TimerEventProcessor);
// Sets the timer interval to 5 seconds.
myTimer.Interval = 5000;
myTimer.Start();
// Runs the timer, and raises the event.
while(exitFlag == false) {
// Processes all the events in the queue.
Application.DoEvents();
}
return 0;
}
I may be mistaken, but I think that this code will help you resolve your problem. DispatcherTimer
DispatcherTimer dispathcerTimer = new DispatcherTimer();
dispathcerTimer.Interval = TimeSpan.FromMinutes(2);
dispathcerTimer.Tick += dispathcerTimer_Tick;
dispathcerTimer.Start();
void dispatcherTime_Tick(object sender, object e)
{
//function, which needs to be invoked every two minutes.
}
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.
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