System.timer doesnt throw events and console terminates immediatly - c#

I need a timer that executes every minute but i have trouble getting the timer to run at all with code that i used before. so i guess i am doing sth fundamentally wrong that is not code related but even in a just newly created Console project in visual studio community 2017 it doesn't execute the _timer_elapsed method. the console terminates immediately without errors as if it has executed every code
using System;
using System.Timers;
namespace Test
{
class Program
{
static Timer _timer;
public static void Main(string[] args)
{
var timer = new Timer(60000);
timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
timer.Enabled = true;
_timer = timer;
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("test");
}
}
}
what am I missing here?

You need your program to stay alive, rather than return from Main. An quick and easy way to do this is to wait for some input at the end:
public static void Main(string[] args)
{
var timer = new Timer(60000);
timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
timer.Enabled = true;
_timer = timer;
Console.ReadLine();
}

There is no such thing as a bad question.
(Though some questions show more affinity with programming, and some show less.)
If you look at your code, your main sets up a timer and then proceeds to terminate. So, of course your program exits immediately and the timer is never fired.
In order to see your timer firing, your program will need to keep running for at least as long as one period of your timer.

Related

How to stop timer in windows service so that code doesn't hit multiple times?

THIS IS SAMPLE CONSOLE APPLICATION NOT THE ORIGINAL WINDOWS SERVICE
I have below code (sample code only). I want that my timer should execute only once and after that it should stop.
Currently I am using count field to check if the code is already hit or not. It is working fine but I want to optimize the things.
NOTE :
Reason behind using the timer is that during installation of windows service OnStart event shouldn't delay service installation process.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
static class Program
{
static int count = 0;
static void Main()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += OnElapseTime;
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Start();
System.Threading.Thread.Sleep(30000);
timer.Stop();
}
static void OnElapseTime(object sender,
System.Timers.ElapsedEventArgs e)
{
if (count < 1)
{
count++;
Console.WriteLine("Timer ticked...");
Console.ReadLine();
}
}
}
}
Just set the AutoReset to false. This causes the event to be only fired once. You can remove the code using count.
timer.AutoReset = false;
There are multiple ways to achieve what you want, which is essentially a delayed execution.
The simplest in terms of modifying what you have might be something like this:
static void Main()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += OnElapseTime;
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Start();
}
static void OnElapseTime(object sender, System.Timers.ElapsedEventArgs e)
{
var timer = (System.Timers.Timer)sender;
timer.Stop(); // stop the timer after first run
// do the work.. (be careful, this is running on a background thread)
Console.WriteLine("Timer ticked...");
Console.ReadLine();
}
Antoher approcah might be to use the System.Threading.Timer class instead of the System.Timers.Timer and schedule a one time delayed execution:
static void Main()
{
var timer = new System.Threading.Timer(RunDelayed, null, imeSpan.FromSeconds(5).TotalMilliseconds, Timeout.Infinite );
}
private void Callback( Object state )
{
// do the work.. (be careful, this is running on a background thread)
Console.WriteLine("Timer ticked...");
Console.ReadLine();
}
Here is a good article that talks about differences between different timer classes available in .NET: https://web.archive.org/web/20150329101415/https://msdn.microsoft.com/en-us/magazine/cc164015.aspx

C# Pause Program Execution

I am writing a program that will perform an operation every 10 or 15 minutes. I want it to be running all the time, so I need something that is cheap on processing power. What I have read so far seems to suggest that I want to use a Timer. Here is a clip of the code I have so far.
class Program {
private static Timer timer = new Timer();
static void Main(string[] args) {
timer.Elapsed += new ElapsedEventHandler(DoSomething);
while(true) {
timer.Interval = TimerMilliseconds(); // The duration of the wait will differ each time
timer.Enabled=true;
}
}
}
The problem here is that the while loop just keeps executing rapidly. How do I halt execution until the timer is elapsed. My program really doesn't need to be multi threaded. Is a Timer the right tool for this job?
Thank you in advance for any help!
UPDATE: Sorry for the confusion. I have implemented the DoSomething method. I just did not include it as I don't believe it is part of my issue.
Timer's will fire off the Elapsed event once the specified interval has elapsed.
I would do something like this:
private static Timer timer = new Timer();
static void Main(string[] args)
{
timer.Elapsed += new ElapsedEventHandler(DoSomething);
timer.Interval = TimerMilliseconds(); // The duration of the wait will differ each time
timer.Enabled=true;
Console.ReadKey(); //Wait for keypress to terminate
}
You could also implement this as a service so you don't have to have a blocking call like Console.ReadKey to keep the program from terminating.
Finally, you could just change the interval in the event handler:
static void DoSomething(...)
{
timer.Stop();
timer.Interval = TimerMilliseconds();
...
timer.Start();
}
The problem with this code is that you're using a loop to set the Interval and Enabled properties of the Timer, which will execute said assignments over and over - it's not waiting for the timer to execute in some way.
If your application doesn't need to be mutlithreaded, then you might be better simply calling Thread.Sleep between executions.
class Program {
static void Main(string[] args) {
while(true) {
Thread.sleep(TimerMilliseconds()); // The duration of the wait will differ each time
DoSomething();
}
}
}
take out the timer and loop from your logic. Just use windows scheduler to execute your program after 15 minutes. Or you can use windows services. Please read Best Timer for using in a Windows service
remove the while loop completely.
inside of the DoSomething() function (once implemented) stop timer at start and at the end reset the interval before restarting the timer.
I guess the comments and answrs already provide the hints you need, but the MSDN docs for Timer actually provide a nice example. In my opinion the Timer approach is a bit tidier, it's easier to read your intentions and abstracts away the details of invoking your scheduled code.
Here's another alternative approach using ManualResetEvent and WaitOne(). This will allow you to halt the main thread without worrying about it being killed accidentally by an errant keypress. You can also Set() the MRE when certain conditions are met to allow the app to exit gracefully:
class Program
{
private static Timer timer;
private static ManualResetEvent mre = new ManualResetEvent(false);
static void Main(string[] args)
{
timer = new Timer(TimerCallback, null, 0, (int)TimeSpan.FromMinutes(15).TotalMilliseconds);
mre.WaitOne();
}
private static void TimerCallback(object state)
{
// ... do something in here ...
Console.WriteLine("Something done at " + DateTime.Now.ToString());
}
}

Timer doesn't want to start again after it was disabled

I am writing a simple C# program that attempts to do something every x amount of seconds using System.Forms.Timer
The tick event calls a method that starts a new thread and disables the timer, then when the thread is done with its work, it enables the timer again, but the problem is, now it doesn't tick after it's been enabled.
static System.Windows.Forms.Timer testtimer = new System.Windows.Forms.Timer();
static void Main()
{
testtimer.Tick += testtimertick;
testtimer.Interval = 5000;
testtimer.Enabled = true;
testtimer.Start();
while (true)
{
Application.DoEvents(); //Prevents application from exiting
}
}
private static void testtimertick(object sender, System.EventArgs e)
{
testtimer.Enabled = false;
Thread t = new Thread(dostuff);
t.Start();
}
private static void dostuff()
{
//Executes some code
testtimer.Enabled = true; //Re enables the timer but it doesn't work
testtimer.Start();
}
As #grzenio said, it appears that your issue has to do with the fact that you are making cross thread calls to a Windows Form Control that was created on a different thread.
If you are using .NET 4.5 (C# 5.0), I would suggest looking at the async/await keywords, a good introduction can be found at Stephen Cleary's Blog
An example of how you could use async and await with your legacy "DoStuff":
private async void _Timer_Tick(object sender, EventArgs e)
{
_Timer.Enabled = false;
await Task.Run((() => DoStuff()));
_Timer.Enabled = true;
}
Things to notice:
async was added to the Timer_Tick event's signature.
The await keyword along with Task.Run was used to asynchronously run the DoStuff.
When using these keywords, the DoStuff will be run asynchronously and once DoStuff returns, it will continue on the line after await using the context of the thread that originally called Tick.
Don't use a GUI timer without a GUI. Don't spin with DoEvents because you are burning 100% of a CPU core with that. Use a System.Threading.Timer. It will just work.
Windows Forms controls are not thread safe, you should make sure you use them on the UI thread, see e.g. C# Windows Forms Application - Updating GUI from another thread AND class?
You can use System.Threading.Timer to do what you want to do, using the Change Method to set the time and the Period, Just restart it when you finish your work.
class Program
{
static System.Threading.Timer testtimer;
static void Main(string[] args)
{
testtimer = new System.Threading.Timer(testtimertick);
testtimer.Change(5000,0);
Console.ReadLine();
}
private static void testtimertick(object sender)
{
Thread t = new Thread(dostuff);
t.Start();
}
private static void dostuff()
{
//Executes some code
Thread.Sleep(2000);
Console.WriteLine("Tick");
testtimer.Change(5000, 0);
}
}
static System.Windows.Forms.Timer testtimer = new System.Windows.Forms.Timer();
static void Main()
{
testtimer.Tick += testtimertick;
testtimer.Interval = 5000;
testtimer.Enabled = true;
while (true)
{
Application.DoEvents(); //Prevents application from exiting
}
}
private static void testtimertick(object sender, System.EventArgs e)
{
Thread t = new Thread(dostuff);
t.Start();
}
private static void dostuff()
{
testtimer.Enabled = false;
//Executes some code
testtimer.Enabled = true; //Re enables the timer but it doesn't work
testtimer.Start();
}
I had a similar issue just now. I was disabling the timer and enabling again whenever I want.
The next time when I enable, it won't work.
I tried disposing the Timer object when I want to disable and creating new instance of it each time I want to enable it. Didn't work though.
Figured out a solution then. I'm removing the event which is configured in testtimer.Tick, and then adding it back when I want to enable the timer.
So the timer internally will be always instantiated with valid values and have its property Enabled = true. The only difference is that it won't have anything actually to perform whenever a tick event triggers.
This would imitate disabling and enabling the timer and makes it working as good as you control like Enabled = false / true.
If you really want to stick to the GUI timer, and start it from non UI thread, you can try to do similar stuff, then write to GUI from non UI thread.
Not the ideal solution, I know.
this.Invoke((MethodInvoker)delegate
{
refreshTimer.Enabled = true;
refreshTimer.Start();
});

Prevent my console application from closing after a .Net.Timer starts

So I have this simple code:
static void Main(string[] args)
{
var timer = new Timer(0.5 * 60 * 1000); // 0.5 minutes times 60 seconds times 1000 miliseconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(Start);
timer.AutoReset = true;
timer.Start();
}
Which starts a timer that starts the whole program logic. Problem is, the console application closes and nothing is done. How do I prevent this? I know that if I do something like while(true) it works, but that does not seem like an elegant/proper solution.
Maybe try
Console.Read();
At the end of the code
Thanks to this your console window will not be closed as long as a user will not press a key.
The last answer is 7 years old. In the meantime, methods from System.Threading like Timer, Sleep, ...
should not be used anymore. They carry the risk of deadlocks, and I have to warn against their use especially in ASP.NET Core.
There are several things to consider:
No program runs forever. What happens when the program should be closed (by a shutdown or a signal)?
The termination must be implemented in your program logic. Many async .NET Core methods supports a CancellationToken as a parameter.
There are 2 approaches to create an "endless" program:
Worker Services in .NET Core are the common approach today to write programs that should run permanently as a service. They can be registered as Windows Service.
More Infos on learn.microsoft.com and devblogs.microsoft.com if you want to register your service as a "real" service.
If you need a "real" console application that performs tasks in the foreground, this can be done with the following sample code:
using System;
using System.Threading.Tasks;
using System.Threading;
namespace DemoApp
{
internal class Program
{
private static int _isRunning = 0;
private static async Task Main(string[] args)
{
// No program can run infinitely. We always have to provide a mechanism for termination.
var tcs = new CancellationTokenSource();
var periodTimeSpan = TimeSpan.FromSeconds(10);
// This mechanism is CTRL+C, so we catch this.
Console.CancelKeyPress += (sender, e) =>
{
tcs.Cancel();
e.Cancel = true;
};
try
{
// No endless loop. We are checking for a cancellation request!
while (!tcs.IsCancellationRequested)
{
// Perform your work.
var task1 = Run(tcs.Token);
var task2 = Task.Delay(periodTimeSpan, tcs.Token);
// If the execution time of Run is greater than periodTimeSpan, we will wait. Depends on your needs.
await Task.WhenAll(task1, task2);
}
}
catch (TaskCanceledException)
{
Console.WriteLine("User canceled your app.");
}
}
private static async Task Run(CancellationToken token)
{
// Should never occur if you use WhenAll()
if (Interlocked.Exchange(ref _isRunning, 1) == 0)
{
// Perform your work.
_isRunning = 0;
}
}
}
}
Add a Console.ReadKey(); this will allow you to close the console window by pressing any key.
static void Main(string[] args)
{
var timer = new Timer(0.5 * 60 * 1000); // 0.5 minutes times 60 seconds times 1000 miliseconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(Start);
timer.AutoReset = true;
timer.Start();
Console.ReadKey();
}
If you want to just run a timer and wait, then Console.Read() is your friend.
The reason why your code is terminating is because the function initializes the timer, starts it and then ... hits the end of the Main function. As a result, the function exits.
The current code doesn't do anything useful (besides starting a timer which is ignored).
If you want to see your timer in action, do some other work after you start the timer. Then, stop the timer after an interval and print it/evaluate it how you deem fit. (The timer doesn't run on the main thread, whereas something like Console.Read() will be on the main thread and thus, block the thread until you have input)
Your console application does not end because the timer starts. It ends because the program reaches the end of the Main() method.
Whatever action you take to prevent the program from exiting Main() will help. While many proposed solutions actually do this. I wanted to highlight the fact that it's not the timer causing the issue.

Need timer to run after 10 seconds in C#

I am working with socket programing ,I can to check the live connection of Users after some time intervals such as 10 seconds.But currently, i have no idea. how i will do it.
Please help me. I shall be highly thankful.
From MSDN Timer Class (System Timers):
Below is an example from the MSDN page
[C#]
public class Timer1
{
public static void Main()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 10 seconds.
aTimer.Interval=10000;
aTimer.Enabled=true;
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read()!='q');
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("Hello World!");
}
}
Include: using System.Threading;
I have no idea what you are doing (have code to show us?), but here's the general logic:
while (/*connection is active*/)
{
//check connection
Thread.Sleep(10000); //10 seconds
}
It really depends on what your doing, and how you are checking for the connection.
You can use the Threading.sleep(); a timer, or depending on what your doing you might be able to use an event handler based off of connects / disconnects...

Categories