How to Add a Timer to a C# Console Application

How do you add a timer to a C# console application

That's very nice, however in order to simulate some time passing we need to run a command that takes some time and that's very clear in second example.

However, the style of using a for loop to do some functionality forever takes a lot of device resources and instead we can use the Garbage Collector to do some thing like that.

We can see this modification in the code from the same book CLR Via C# Third Ed.

using System;
using System.Threading;

public static class Program
{
private Timer _timer = null;
public static void Main()
{
// Create a Timer object that knows to call our TimerCallback
// method once every 2000 milliseconds.
_timer = new Timer(TimerCallback, null, 0, 2000);
// Wait for the user to hit <Enter>
Console.ReadLine();
}

private static void TimerCallback(Object o)
{
// Display the date/time when this method got called.
Console.WriteLine("In TimerCallback: " + DateTime.Now);
}
}

Countdown timer in console Application

There are two ways i know of doing what you want

1) Use Console.SetCursorPosition();. This is applicable when you are sure of the amount of characters that will be above the timer.

2) Use Console.CursorLeft. This is applicable in all cases.

Code Examples

static void Main(string[] args)
{
for (int a = 10; a >= 0; a--)
{
Console.SetCursorPosition(0,2);
Console.Write("Generating Preview in {0} ", a); // Override complete previous contents
System.Threading.Thread.Sleep(1000);
}
}

static void Main(string[] args)
{
Console.Write("Generating Preview in ");
for (int a = 10; a >= 0; a--)
{
Console.CursorLeft = 22;
Console.Write("{0} ", a ); // Add space to make sure to override previous contents
System.Threading.Thread.Sleep(1000);
}
}

timer in console application

You could create and dispose it in Main() and pass it to any methods that require it?

private static void Main()
{
using (var timer = new System.Threading.Timer(TimerProc))
{
// Rest of code here...
}
}

More importantly, this line of code:

Thread.CurrentThread.Join();

will never return, because you are asking the current thread to wait for the current thread to terminate. Think about that for a moment... ;)

So your solution is probably to just remove that line of code.

C# | Console app | How to make the program wait (time in ms) before executing the next line?

A slightly different approach would be to use the Stopwatch class to measure time, and only change the text if we've passed the specified "flash interval".

We could write a method to do this, which would take in a string prompt to display, and a TimeSpan interval that specifies how long to wait between flashing the text.

In the code, we would capture the cursor position and console colors, start a stopwatch, and then every time the stopwatch passes the amount of time specified by interval, we would swap the Console.ForegroundColor and Console.BackgroundColor.

The method would do this until the user presses a key, which we would return back to the caller:

private static ConsoleKey FlashPrompt(string prompt, TimeSpan interval)
{
// Capture the cursor position and console colors
var cursorTop = Console.CursorTop;
var colorOne = Console.ForegroundColor;
var colorTwo = Console.BackgroundColor;

// Use a stopwatch to measure time interval
var stopwach = Stopwatch.StartNew();
var lastValue = TimeSpan.Zero;

// Write the initial prompt
Console.Write(prompt);

while (!Console.KeyAvailable)
{
var currentValue = stopwach.Elapsed;

// Only update text with new color if it's time to change the color
if (currentValue - lastValue < interval) continue;

// Capture the current value, swap the colors, and re-write our prompt
lastValue = currentValue;
Console.ForegroundColor = Console.ForegroundColor == colorOne
? colorTwo : colorOne;
Console.BackgroundColor = Console.BackgroundColor == colorOne
? colorTwo : colorOne;
Console.SetCursorPosition(0, cursorTop);
Console.Write(prompt);
}

// Reset colors to where they were when this method was called
Console.ForegroundColor = colorOne;
Console.BackgroundColor = colorTwo;

return Console.ReadKey(true).Key;
}

Now, on the calling side, we would pass it the text "Press escape to continue" and the amount of time we want to wait (TimeSpan.FromMilliseconds(500) in your case), and then we could call this in an infinite while loop, until the user presses ConsoleKey.Escape:

private static void Main()
{
// Flash prompt until user presses escape
while (FlashPrompt("Press escape to continue...",
TimeSpan.FromMilliseconds(500)) != ConsoleKey.Escape) ;

// Code execution continues after they press escape...
}

The nice thing here is that you can re-use the logic and can specify shorter or longer flash times. You can also change the colors that get "flashed" by specifying them before calling the method (or the method could be written to take them as arguments).

For example, try this out:

private static void Main()
{
Console.WriteLine("Hello! The text below will flash red " +
"and green once per second until you press [Enter]");

Console.ForegroundColor = ConsoleColor.Red;
Console.BackgroundColor = ConsoleColor.Green;

while (FlashPrompt("Press [Enter] to continue...",
TimeSpan.FromSeconds(1)) != ConsoleKey.Enter) ;

Console.ResetColor();

// Code will now continue in the original colors
}

Using System.Timers with a console application and output type 'Windows Application'

To achieve what you want:

using System;
using System.Diagnostics;
using System.Timers;

public class Program
{
private static Timer _Timer;
private static bool Launched = false;
static void Main(string[] args)
{
SetupTimer();
WaitUntilItIsLaunched:
if (!Launched)
{
System.Threading.Thread.Sleep(100);
goto WaitUntilItIsLaunched;
}
}

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Process.Start(@"C:\WINDOWS\system32\notepad.exe");
Launched = true;
}

private static void SetupTimer()
{
_Timer = new Timer();
_Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
_Timer.Interval = 3000;
_Timer.Enabled = true;
}
}

Timer Working for two times only , c# console application

You are cresting a LOCAL variable of your Timer, you should instead use your GLOBAL instance, like this:

    public void init()
{
_urlService = customConfig["DemoUrlService"];
// onStart();
aTimer = new Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = Convert.ToDouble(getIntervialTimeIntervalTime());
aTimer.AutoReset = true;
aTimer.Enabled = true;
}

The problem, when you use a local Timer, is that when the method exits, the Timer get garbage collected and of course stops working.



Related Topics



Leave a reply



Submit