Reputation: 5689
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.
Upvotes: 5
Views: 3221
Reputation: 1276
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:
There are 2 approaches to create an "endless" program:
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;
}
}
}
}
Upvotes: 3
Reputation: 326
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)
Upvotes: 1
Reputation: 4094
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();
}
Upvotes: 1
Reputation: 59259
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.
Upvotes: 0
Reputation: 6366
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.
Upvotes: 10