Why I can't modify Timer.ineterval during runtime? - c#

Here is the scenario I'm trying to achieve,
My program has a timer which its interval is set to 10 seconds (10000ms).
I want to check for a specific conditions, for example if a specific file exists or has changed, then change timer.interval accordingly.
Here's my code:
static void Main(string[] args)
{
timer.Interval =10000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(WriteToConsole);
timer.Start();
if(fileExists(#"C:\temp\1.txt"))
{
timer.Interval =20000; //20 seconds
}
else if(fileExists(#"C:\temp\2.txt"))
{
timer.Interval =15000; // 15 seconds
}
}
public static void WriteToConsole(object sender, System.Timers.ElapsedEventArgs args)
{
Console.WriteLine(DateTime.UtcNow);
}
But it doesn't work as I need it to.
I've already read these but couldn't find the solution.
1-2-3

Try writing your start after you specify your interval, or else stop the timer and start again later.

Related

C# Timer.Elapsed Event firing twice consecutively

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);

Print something to console after x milliseconds

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.

C# Windows Service While loop

I have a problem with a windows service.
protected override void OnStart(string[] args)
{
while (!File.Exists(#"C:\\Users\\john\\logOn\\oauth_url.txt"))
{
Thread.Sleep(1000);
}
...
I have to wait for a particular file, thus while loop is necessary, but the service will not be able to start with loop like this. What I can do to have a running service and a mechanism that checks if a file exists ?
The best option is to have a timer System.Timers.Timer in your service.
System.Timers.Timer timer = new System.Timers.Timer();
In the constructor add the handler for the Elapsed event:
timer.Interval = 1000; //miliseconds
timer.Elapsed += TimerTicked;
timer.AutoReset = true;
timer.Enabled = true;
Then in the OnStart method start that timer:
timer.Start();
In the event handler do your work:
private static void TimerTicked(Object source, ElapsedEventArgs e)
{
if (!File.Exists(#"C:\Users\john\logOn\oauth_url.txt"))
return;
//If the file exists do stuff, otherwise the timer will tick after another second.
}
A minimal service class will look somewhat like this:
public class FileCheckServivce : System.ServiceProcess.ServiceBase
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
public FileCheckServivce()
{
timer.Elapsed += TimerTicked;
timer.AutoReset = true;
timer.Enabled = true;
}
protected override void OnStart(string[] args)
{
timer.Start();
}
private static void TimerTicked(Object source, ElapsedEventArgs e)
{
if (!File.Exists(#"C:\Users\john\logOn\oauth_url.txt"))
return;
//If the file exists do stuff, otherwise the timer will tick after another second.
}
}
I would consider using FileSystemWatcher as that is exactly what it is intended for, to monitor changes on the filesystem. Once event is raised on a folder, you can check if that particular file exists.
The default example in MSDN actually shows monitoring of .txt file https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx

How to run a thread until a condition becomes true in c#

I am writing a program to send SMS every 5 minutes. I want to stop this when the system time is 6 PM. How can I do that? This is my current code.
I want to modify this according to my above requirement.
while (true)
{
sms.SendSMS();
Thread.Sleep(30000);
}}).Start();
}
Generally never use Sleep is bad idea , use timer instead:
System.Timers.Timer SendSMS = new System.Timers.Timer();
SendSMS.Interval = 300000; ///300000ms=5min
SendSMS.Elapsed += new System.Timers.ElapsedEventHandler(SendSMS_Elapsed);
SendSMS.Enabled=true;
void SendSMS_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
sms.SendSMS();
}
Add a second timer to check the time and stop when is 6pm:
System.Timers.Timer StopSendSMS = new System.Timers.Timer();
StopSendSMS.Interval = 100;
StopSendSMS.Elapsed += new System.Timers.ElapsedEventHandler( StopSendSMS_Elapsed);
StopSendSMS.Enabled=true;
void StopSendSMS_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (int(DateTime.Now.Hour)==18))
{
SendSMS.Enabled=false;
StopSendSMS.Enabled=false; ///no need to check anymore
}
}
You can use the below condition to check system TIME.
`if(DateTime.Now.Hour.ToString("HH") == "18") //Hour is in 24hour format`

How to delay a method in C# for Windows Phone 7?

I have a method.
public bool bBIntersectsBT(Rect barTopTipRect, Rect barBottomTipRect, Rect blueBallRect)
{
barTopTipRect.Intersect(blueBallRect);
barBottomTipRect.Intersect(blueBallRect);
if (barTopTipRect.IsEmpty && barBottomTipRect.IsEmpty)
{
return false;
}
else
{
return true;
}
}
I want to delay this method for 2 seconds before this method is executed again. I have read up about Thread.Sleep, However, that is not what I want. I do not want the program to pause and resume it.
Use a DispatcherTimer:
DispatcherTimer timer = new DispatcherTimer();
//TimeSpan is in format: Days, hours, minutes, seconds, milliseconds.
timer.Interval = new TimeSpan(0, 0, 0, 2);
timer.Tick += timerTick;
timer.Start();
private void timerTick(Object sender, EventArgs e)
{
//Your code you want to execute every 2 seconds
//If you want to stop after the two seconds just add timer.Stop() here
}
You can user Dispatch Timer to achieve your goal. Set it to 2 seconds when you want. And after you are done with it. you can stop it.

Categories

Resources