using System; using System.Threading; class Program { static void Main(string[] args) { // Loop tests to demonstrate the progress bar Test("Normal test", 10, false); Test("Abort test", 60, true); Test("Fast test", 5, false); Test("Slow test", 40, false); Console.ResetColor(); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } private static void Test(string text, int sleepTimeout, bool shouldAbort) { // Reset the progress bar and console color, etc. ConsoleProgress.Reset(); Console.ResetColor(); Console.WriteLine(text); Console.WriteLine(); Console.ForegroundColor = ConsoleColor.DarkGray; for (int i = 0, max = 400; i <= max && !ConsoleProgress.Canceled; i++) { ConsoleProgress.Update(i, max); if (shouldAbort && i > 70) ConsoleProgress.Canceled = true; Thread.Sleep(sleepTimeout); } Console.WriteLine(); // Signal result if (ConsoleProgress.Canceled) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Operation canceled!"); } else { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine("Operation completed successfully!"); } Console.WriteLine(); Console.WriteLine(); } } static class ConsoleProgress { #region Fields private static int lastProgress = -1; private static float lastPercent = 0; private static bool reset = true; private static bool operationCanceled = false; #endregion #region Properties public static bool Canceled { get { return operationCanceled; } set { operationCanceled = value; Update(); } } #endregion #region Methods public static void Reset() { reset = true; operationCanceled = false; } private static void Update() { Update(lastPercent); } public static void Update(int currentPosition, int maximum) { if (currentPosition < 0 || maximum < 1) throw new ArgumentOutOfRangeException("Values must be positive!"); if (currentPosition > maximum) throw new ArgumentOutOfRangeException("currentPosition", "currentPosition must be less than, or equal to maximum!"); Update((float)currentPosition / maximum); } public static void Update(float percent) { // Reserved for '[' ']', a space and percent text const int reserved = 2 + 6; // Sanity check if (percent < 0 || percent > 1) throw new ArgumentOutOfRangeException("percent", "Invalid progress value!"); // Calculate the number of dashes and white spaces we need. int capacity = Console.BufferWidth; int dashes = (int)(percent * (capacity - reserved)); int spaces = capacity - reserved - dashes; lastPercent = percent; // Only update the progress bar when there is a full percent change // Otherwise, there might be performance hits if (lastProgress != dashes || operationCanceled || reset) { string progressText = string.Format( "[{0}{1}] {2}", new string('-', dashes), new string(' ', spaces), operationCanceled ? "Abort" : string.Format("{0,5:P0}", percent)); // Clear the last line, update text if (Console.CursorTop > 0 && !reset) Console.CursorTop--; Console.Write(progressText); // Save the new state lastProgress = dashes; reset = false; } } #endregion }