Progress bar in console application

I was also looking for a console progress bar. I didn't find one that did what I needed, so I decided to roll my own. Click here for the source code (MIT License).

Animated progress bar

Features:

  • Works with redirected output

    If you redirect the output of a console application (e.g., Program.exe > myfile.txt), most implementations will crash with an exception. That's because Console.CursorLeft and Console.SetCursorPosition() don't support redirected output.

  • Implements IProgress<double>

    This allows you to use the progress bar with async operations that report a progress in the range of [0..1].

  • Thread-safe

  • Fast

    The Console class is notorious for its abysmal performance. Too many calls to it, and your application slows down. This class performs only 8 calls per second, no matter how often you report a progress update.

Use it like this:

Console.Write("Performing some task... ");
using (var progress = new ProgressBar()) {
    for (int i = 0; i <= 100; i++) {
        progress.Report((double) i / 100);
        Thread.Sleep(20);
    }
}
Console.WriteLine("Done.");

I know this is an old thread, and apologies for the self promotion, however I've recently written an open source console library available on nuget Goblinfactory.Konsole with threadsafe multiple progress bar support, that might help anyone new to this page needing one that doesnt block the main thread.

It's somewhat different to the answers above as it allows you to kick off the downloads and tasks in parallel and continue with other tasks;

cheers, hope this is helpful

A

var t1 = Task.Run(()=> {
   var p = new ProgressBar("downloading music",10);
   ... do stuff
});

var t2 = Task.Run(()=> {
   var p = new ProgressBar("downloading video",10);
   ... do stuff
});

var t3 = Task.Run(()=> {
   var p = new ProgressBar("starting server",10);
   ... do stuff .. calling p.Refresh(n);
});

Task.WaitAll(new [] { t1,t2,t3 }, 20000);
Console.WriteLine("all done.");

gives you this type of output

enter image description here

The nuget package also includes utilities for writing to a windowed section of the console with full clipping and wrapping support, plus PrintAt and various other helpful classes.

I wrote the nuget package because I constantly ended up writing lots of common console routines whenever I wrote build and ops console scripts and utilities.

If I was downloading several files, I used to slowly Console.Write to the screen on each thread, and used to try various tricks to make reading the interleaved output on the screen easier to read, e.g. different colors or numbers. I eventually wrote the windowing library so that output from different threads could simply be printed to different windows, and it cut down a ton of boilerplate code in my utility scripts.

For example, this code,

        var con = new Window(200,50);
        con.WriteLine("starting client server demo");
        var client = new Window(1, 4, 20, 20, ConsoleColor.Gray, ConsoleColor.DarkBlue, con);
        var server = new Window(25, 4, 20, 20, con);
        client.WriteLine("CLIENT");
        client.WriteLine("------");
        server.WriteLine("SERVER");
        server.WriteLine("------");
        client.WriteLine("<-- PUT some long text to show wrapping");
        server.WriteLine(ConsoleColor.DarkYellow, "--> PUT some long text to show wrapping");
        server.WriteLine(ConsoleColor.Red, "<-- 404|Not Found|some long text to show wrapping|");
        client.WriteLine(ConsoleColor.Red, "--> 404|Not Found|some long text to show wrapping|");

        con.WriteLine("starting names demo");
        // let's open a window with a box around it by using Window.Open
        var names = Window.Open(50, 4, 40, 10, "names");
        TestData.MakeNames(40).OrderByDescending(n => n).ToList()
             .ForEach(n => names.WriteLine(n));

        con.WriteLine("starting numbers demo");
        var numbers = Window.Open(50, 15, 40, 10, "numbers", 
              LineThickNess.Double,ConsoleColor.White,ConsoleColor.Blue);
        Enumerable.Range(1,200).ToList()
             .ForEach(i => numbers.WriteLine(i.ToString())); // shows scrolling

produces this

enter image description here

You can also create progress bars inside a window just as easily as writing to the windows. (mix and match).