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
Escape Double Quotes in a String
Show/Hide the Console Window of a C# Console Application
How to Add a New Row to Datagridview Programmatically
Random.Next Returns Always the Same Values
Replacing .Net Webbrowser Control With a Better Browser, Like Chrome
Difference Between Covariance & Contra-Variance
How to Load Image to Wpf in Runtime
Why Is Dictionary Preferred Over Hashtable in C#
Best Practices For Catching and Re-Throwing .Net Exceptions
Creating a Datetime in a Specific Time Zone in C#
How to Use Reflection to Invoke a Private Method
Given a Filesystem Path, Is There a Shorter Way to Extract the Filename Without Its Extension
How to Cast Object of Type 'System.Dbnull' to Type 'System.String'
Visual Studio Publish Project into One Simple Installer