I'm trying to use a timer in C# to run a method at an interval of five seconds. Though this code doesn't seem to work. I do not get any errrors when running it but the program (I run this in a console) shuts down right after IP.timer1.Start(). The timer1_Elapsed method is never getting executed. I know that because I've tried making the program print a string to the console at the first line of the timer1_Elapsed method.
class Program
{
Timer timer1 = new Timer();
static void Main(string[] args)
{
Program IP = new Program();
IP.timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
IP.timer1.Interval = 5000;
IP.timer1.Enabled = true;
IP.timer1.Start();
}
static void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
//Function to get executed each time the counter elapses.
}
}
The reason is that the Start method of the timer starts the timer on another thread, and immediately returns from the method. This causes your Main method to end, and the console to shut down.
Depending on what Timer you are using (there are a few similarly named classes in the BCL) you may want to implement the fix differently. I suggest reading the documentation on System.Timers.Timer, System.Windows.Forms.Timer or System.Threading.Timer depending on which it is you are using.
Your program will exit the moment the main function terminates.
You need to prevent main from exiting until you are ready, possibly with a Console.ReadLine();
The timer starts on another thread, Use the following to suspend the thread until the user hits a key after the timer start.
Console.ReadLine();
The reason that the program exits right after IP.timer1.Start() is that it is done executing the Main()-function and there is nothing stopping it from returning.
If you want a simple way to keep your program running you can add Console.ReadKey(); after timer1.Start(); so that your application will wait until that function returns (which is when you press any key). After doing this your callback should be called every five seconds as specified.
Related
My Question is more about getting to the same destination, but there must be another way. Right now im creating a DateTime and compare that to another DateTime and check, if the time difference I set up might be right. So far so good but I just can't accept that I create a new propertie everytime the loop will get into that code.
Is there any possible way to get to the same destination, but in some kind of more effective way?
I got you guys some example code here:
private void RunService()
{
// Runs as long as the service didn't got a stop call.
while (!SetStop)
{
//Get MinutesToWait
this.MinutesToWait = 5;
DateTime CheckRunTime = this.LastRun;
CheckRunTime.AddMinutes(this.MinutesToWait);
if (DateTime.Now >= CheckRunTime)
{
// Imagine some good and smart and totally runnable code?
}
}
}
If I understood correctly, what you want to do is execute a piece of code some time after the service starts. If that is the case, then your best bet would be to use a timer.
First off, you have to convert the amount of time you want to wait to milliseconds. For example, 5 minutes equals 300000ms. Then, you have to move the code you want to execute to a separate method. I will name this method RunCode() for the example. Finally, you create your timer like so:
private void RunService()
{
var timer = new Timer(300000);
timer.Elapsed += (s, e) => this.RunCode();
timer.Start();
Thread.Sleep(Timeout.Infinite);
}
What we are doing here is the following.
Instantiating the timer with an interval of 300000ms
Subscribing to the timer's Elapsed event, which fires when the specified time has passed
Starting the timer
Sleeping our main thread forever. This line is optional. Whether you need it or not depends on the structure of your program. If nothing else happens in your code after you start the timer, the main thread and by extension the whole program will exit. However by sleeping it with an infinite timeout, we can prevent that.
If you're sure that this, delayed execution of code, is what you want, then the solution I have provided should work quite well. However I'm worried this may be an XY problem, meaning this is the solution you have come up with for a different issue which could be solved better. So I have to ask, why exactly do you need this in your service?
Use System.Timers
static void Main(string[] args) {
Timer T = new Timer();
T.Elapsed += Run;
T.Interval = 100;
T.Start();
}
static void Run(object source, ElapsedEventArgs e) {
}
Part of my program receives input over a network connection, and sends a message back. I want to limit the number of times a certain input can trigger a message, so the program can't be overloaded.
I have a background worker that waits for the input, and then when it receives the certain input, it calls into a static class that will determine if it has been enough time since the last input. I'm using a
System.Windows.Forms.Timer
To do this. It looks like this (everything is public so I can debug):
public static class InputResponse
{
public static System.Windows.Forms.Timer Time = new System.Windows.Forms.Timer();
public static void CreateTimer()//set all the properties of the timer
{
Time.Interval = 3000;
Time.Tick += new EventHandler(Time_Tick);
}
public static void InputAReceived()
{
if (Time.Enabled) //if the timer is running, do nothing
return;
else
{
//send response here
Time.Start();
}
}
public static void Time_Tick(object sender, EventArgs e)
{
Console.WriteLine("Time_Tick");
Time.Stop();
}
}
The problem is, the Time_Tick method never gets called from the timer. I can use Invoke() to trigger the method like so,
EventHandler testHandler = new EventHandler(InputResponse.Time_Tick);
testHandler.Invoke(sender, e);//triggered by a button
which writes to the console like it should, but just waiting for the timer doesn't work. It will send the response once, and then won't send it again, since the timer never gets stopped.
The ridiculous thing is I have it working almost exactly the same in another class. The only difference is that the timer is constantly running.
What am I missing?
One problem with your code is that it is using the System.Windows.Forms.Timer class from a background thread and not associated with a window. This violates the instructions given in the documentation:
This timer is optimized for use in Windows Forms applications and must be used in a window.
For timers not related to GUI objects, use System.Timers.Timer.
This may or may not be the cause of the problems you're having, but it's one thing you'll need to address for your code to work correctly.
I have a console app that runs some on demand reporting in a webapplication. The app starts, runs some housecleaning, starts a (1 second) timer, and blocks on a Console.ReadLine(); statement. (I've been meaning to stuff it into a service instead, but that's for another day)
Right now this has no exception-handling, so if the sql server it polls against goes down or there is a network hiccup, it just crashes. I'm trying to implement a crude exception-handling now. Inside the timer-callback I have stuffed the sql-query inside a trycatch. If it fails, it handles the exception by logging, increasing a failurecounter and resuming the timer. If it fails more than 5 times I want it to exit the app (sort of) gracefully. How can I force-quit a console app that is blocked with a readline statement?
Code in a gist: https://gist.github.com/cwattengard/11171563
I think a more elegant solution is to block with a reset event. The timer callback sets this at some point when it considers that it no longer has work to do.
static readonly ManualResetEvent reset = new ManualResetEvent(false);
static void Main(string[] args)
{
var t = new Timer(TimerCallback, null, -1, 1000);
t.Change(0, 1000);
reset.WaitOne(); // the application will sit here until the timer tells it to continue.
}
private static void TimerCallback(object state)
{
try
{
// do stuff.
}
catch (Exception e)
{
failureCounter++;
if (failureCounter > 5)
{
reset.Set(); // release the reset event and the application will exit,
return;
}
}
}
The best way would be to use some sort of signalling mechanism.
For example you start the main thread, do all your initialization (timer etc) then create a non signaled ManualResetEvent and wait on it to fire. If the callback from the timer decides the application should terminate it signals the ManualResetEvent and the main thread is released, completes, and terminates the program...
As a matter of general approach, you should always use signaling and ""cooperative multi-tasking"" within your application. In the sense you signal other threads\ tasks\ actors\ whatever to do stuff, you shouldn't forcefully kill them...
I am having a problem getting the main Form in my program to run as I want. I am using C#. On my initial main form (Form1) I have a command button that runs a long program. In the middle of the program I want the user to be able go back to the initial form and click on some new checkboxes that I will place on that initial form from within the C# program. The code below just freezes the initial form. I do not need to get the code below to work exactly. I just need it to allow me to access the main initial form in the middle of the program that I started with the command button.
To do this I have an infinite while loop that calls the timer. Is this the correct way to do this? I do not need the program below to work. I just need to be able to access that initial Form in the middle of the program. Since it is not working it seems that it is not the way to do this but what is the correct way?
The following code runs the OnTimedEvent function (method) below. The function used to put up a Messagebox but I commented that out. I do NOT need that function to work. It is only there for testing purposes. My goal is that I need the initial main Form to allow me to enter more information while it is running from the command button. The function below runs about 15 times and I get the error
Exception of type 'System.OutOfMemoryException' was thrown.
on the line aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
The code is below:
System.Timers.Timer aTimer;
// Create a timer with a one second interval.
aTimer = new System.Timers.Timer(100);
while (true)
{
// Hook up the event handler for the Elapsed event.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false;
aTimer.Enabled = true; // uncommented this now
//addded below
aTimer.Start();
}
I have tried it in several different ways but the main Form always just freezes. I just want to be able to select things (checkboxes, for instance) on the main Form (Form1) so the below code may not be needed. The timer above calls OnTimedEvent which is below.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// MessageBox.Show("Hello World");
}
In many places on the web I have seen (including stackoverflow) that I should be using timers to get the main initial Form to be useable but the code above just causes the Form to be Frozen and I get the bar at the top of the form indicating that it is Not Responding.
I am using Windows XP and Visual Studio 2008. As I indicated above I am using C#.
To summarize, is the above code the correct way to get the main, Initial form to be available after a command button has been running? If it is, what am I doing wrong? If this is not the correct way, what is?
BTW, I asked a completely unrelated question about this project here
Any ideas?
You should simply remove the while loop
System.Timers.Timer aTimer;
// Create a timer with a one second interval.
aTimer = new System.Timers.Timer(1000);
// Hook up the event handler for the Elapsed event.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false;
aTimer.Enabled = true; // uncommented this now
//addded below
aTimer.Start();
Timer runs on a separate Thread when you start it. Your while loop just keeps starting the timer over and over again.
System.Timers.Timer
To do this I have an infinite while loop that calls the timer. Is this the correct way to do this?
No. The while loop blocks the UI thread, which in turn makes the program freeze. There's no reason to have the while loop as you're already using a timer to trigger the event.
Without seeing your full, actual, code it's hard to say, but the tradtional method of doing a long-running process without locking the UI is to use Threading in C#.
Can you do your long running action in its own thread so that you don't lock up the UI thread?
Here's a tutorial: http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
Don't use a while loop. If you want to run your OnTimedEvent method once a second, use something more like this:
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Interval = 1000; // 1000 ms is one second
myTimer.Enabled = true;
myTimer.Start();
Writing an infinite loop is simple:
while(true){
//add whatever break condition here
}
But this will trash the CPU performance. This execution thread will take as much as possible from CPU's power.
What is the best way to lower the impact on CPU?
Adding some Thread.Sleep(n) should do the trick, but setting a high timeout value for Sleep() method may indicate an unresponsive application to the operating system.
Let's say I need to perform a task each minute or so in a console app.
I need to keep Main() running in an "infinite loop" while a timer will fire the event that will do the job. I would like to keep Main() with the lowest impact on CPU.
What methods do you suggest. Sleep() can be ok, but as I already mentioned, this might indicate an unresponsive thread to the operating system.
LATER EDIT:
I want to explain better what I am looking for:
I need a console app not Windows service. Console apps can simulate the Windows services on Windows Mobile 6.x systems with Compact Framework.
I need a way to keep the app alive as long as the Windows Mobile device is running.
We all know that the console app runs as long as its static Main() function runs, so I need a way to prevent Main() function exit.
In special situations (like: updating the app), I need to request the app to stop, so I need to infinitely loop and test for some exit condition. For example, this is why Console.ReadLine() is no use for me. There is no exit condition check.
Regarding the above, I still want Main() function as resource friendly as possible. Let asside the fingerprint of the function that checks for the exit condition.
To avoid the infinity loop simply use a WaitHandle. To let the process be exited from the outer world use a EventWaitHandle with a unique string. Below is an example.
If you start it the first time, it simple prints out a message every 10 seconds. If you start in the mean time a second instance of the program it will inform the other process to gracefully exit and exits itself also immediately. The CPU usage for this approach: 0%
private static void Main(string[] args)
{
// Create a IPC wait handle with a unique identifier.
bool createdNew;
var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "CF2D4313-33DE-489D-9721-6AFF69841DEA", out createdNew);
var signaled = false;
// If the handle was already there, inform the other process to exit itself.
// Afterwards we'll also die.
if (!createdNew)
{
Log("Inform other process to stop.");
waitHandle.Set();
Log("Informer exited.");
return;
}
// Start a another thread that does something every 10 seconds.
var timer = new Timer(OnTimerElapsed, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
// Wait if someone tells us to die or do every five seconds something else.
do
{
signaled = waitHandle.WaitOne(TimeSpan.FromSeconds(5));
// ToDo: Something else if desired.
} while (!signaled);
// The above loop with an interceptor could also be replaced by an endless waiter
//waitHandle.WaitOne();
Log("Got signal to kill myself.");
}
private static void Log(string message)
{
Console.WriteLine(DateTime.Now + ": " + message);
}
private static void OnTimerElapsed(object state)
{
Log("Timer elapsed.");
}
You can use System.Threading.Timer Class which provides ability to execute callback asynchronously in a given period of time.
public Timer(
TimerCallback callback,
Object state,
int dueTime,
int period
)
As alternative there is System.Timers.Timer class which exposes Elapsed Event which raises when a given period of time is elapsed.
Why would you condone the use of an infinite loop? For this example would setting the program up as a scheduled task, to be run every minute, not be more economical?
Why don't you write a small application and use the system's task scheduler to run it every minute, hour...etc?
Another option would be to write a Windows Service which runs in the background. The service could use a simple Alarm class like the following on MSDN:
http://msdn.microsoft.com/en-us/library/wkzf914z%28v=VS.90%29.aspx#Y2400
You can use it to periodically trigger your method. Internally this Alarm class uses a timer:
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Just set the timer's interval correctly (e.g. 60000 milliseconds) and it will raise the Elapsed event periodically. Attach an event handler to the Elapsed event to perform your task. No need to implement an "infinite loop" just to keep the application alive. This is handled for you by the service.
I did this for an application that had to process files as they were dropped on a folder. Your best bet is a timer (as suggested) with a Console.ReadLine() at the end of "main" without putting in a loop.
Now, your concern about telling the app to stop:
I have also done this via some rudimentary "file" monitor. Simply creating the file "quit.txt" in the root folder of the application (by either my program or another application that might request it to stop) will make the application quit. Semi-code:
<do your timer thing here>
watcher = new FileSystemWatcher();
watcher.Path = <path of your application or other known accessible path>;
watcher.Changed += new FileSystemEventHandler(OnNewFile);
Console.ReadLine();
The OnNewFile could be something like this:
private static void OnNewFile(object source, FileSystemEventArgs e)
{
if(System.IO.Path.GetFileName(e.FullPath)).ToLower()=="quit.txt")
... remove current quit.txt
Environment.Exit(1);
}
Now you mentioned that this is (or could be) for a mobile application? You might not have the file system watcher. In that case, maybe you just need to "kill" the process (you said "In special situations (like: updating the app), I need to request the app to stop". Whoever the "requester" to stop it is, should simply kill the process)
It sounds to me like you want Main() to enter an interruptable loop. For this to happen, multiple threads must be involved somewhere (or your loop must poll periodically; I am not discussing that solution here though). Either another thread in the same application, or a thread in another process, must be able to signal to your Main() loop that it should terminate.
If this is true, then I think you want to use a ManualResetEvent or an EventWaitHandle . You can wait on that event until it is signalled (and the signalling would have to be done by another thread).
For example:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
startThreadThatSignalsTerminatorAfterSomeTime();
Console.WriteLine("Waiting for terminator to be signalled.");
waitForTerminatorToBeSignalled();
Console.WriteLine("Finished waiting.");
Console.ReadLine();
}
private static void waitForTerminatorToBeSignalled()
{
_terminator.WaitOne(); // Waits forever, but you can specify a timeout if needed.
}
private static void startThreadThatSignalsTerminatorAfterSomeTime()
{
// Instead of this thread signalling the event, a thread in a completely
// different process could do so.
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
_terminator.Set();
});
}
// I'm using an EventWaitHandle rather than a ManualResetEvent because that can be named and therefore
// used by threads in a different process. For intra-process use you can use a ManualResetEvent, which
// uses slightly fewer resources and so may be a better choice.
static readonly EventWaitHandle _terminator = new EventWaitHandle(false, EventResetMode.ManualReset, "MyEventName");
}
}
You can use Begin-/End-Invoke to yield to other threads. E.g.
public static void ExecuteAsyncLoop(Func<bool> loopBody)
{
loopBody.BeginInvoke(ExecuteAsyncLoop, loopBody);
}
private static void ExecuteAsyncLoop(IAsyncResult result)
{
var func = ((Func<bool>)result.AsyncState);
try
{
if (!func.EndInvoke(result))
return;
}
catch
{
// Do something with exception.
return;
}
func.BeginInvoke(ExecuteAsyncLoop, func);
}
You would use it as such:
ExecuteAsyncLoop(() =>
{
// Do something.
return true; // Loop indefinitely.
});
This used 60% of one core on my machine (completely empty loop). Alternatively, you can use this (Source) code in the body of your loop:
private static readonly bool IsSingleCpuMachine = (Environment.ProcessorCount == 1);
[DllImport("kernel32", ExactSpelling = true)]
private static extern void SwitchToThread();
private static void StallThread()
{
// On a single-CPU system, spinning does no good
if (IsSingleCpuMachine) SwitchToThread();
// Multi-CPU system might be hyper-threaded, let other thread run
else Thread.SpinWait(1);
}
while (true)
{
// Do something.
StallThread();
}
That used 20% of one core on my machine.
To expound on a comment CodeInChaos made:
You can set a given thread's priority. Threads are scheduled for execution based on their priority. The scheduling algorithm used to determine the order of thread execution varies with each operating system. All threads default to "normal" priority, but if you set your loop to low; it shouldn't steal time from threads set to normal.
The Timer approach is probably your best bet, but since you mention Thread.Sleep there is an interesting Thread.SpinWait or SpinWait struct alternative for similar problems that can sometimes be better than short Thread.Sleep invocations.
Also see this question: What's the purpose of Thread.SpinWait method?
Lots of "advanced" answers here but IMO simply using a Thread.Sleep(lowvalue) should suffice for most.
Timers are also a solution, but the code behind a timer is also an infinity loop - I would assume - that fires your code on elapsed intervals, but they have the correct infinity-loop setup.
If you need a large sleep, you can cut it into smaller sleeps.
So something like this is a simple and easy 0% CPU solution for a non-UI app.
static void Main(string[] args)
{
bool wait = true;
int sleepLen = 1 * 60 * 1000; // 1 minute
while (wait)
{
//... your code
var sleepCount = sleepLen / 100;
for (int i = 0; i < sleepCount; i++)
{
Thread.Sleep(100);
}
}
}
Regarding how the OS detects if the app is unresponsive. I do not know of any other tests than on UI applications, where there are methods to check if the UI thread processes UI code. Thread sleeps on the UI will easily be discovered. The Windows "Application is unresponsive" uses a simple native method "SendMessageTimeout" to see detect if the app has an unresponse UI.
Any infinity loop on an UI app should always be run in a separate thread.
To keep console applications running just add a Console.ReadLine() to the end of your code in Main().
If the user shouldn't be able to terminate the application you can do this with a loop like the following:
while (true){
Console.ReadLine();
}