Share via


Showing Progress in a Console Windows

Recently I needed to show some progress indicator on some long running console application. I recall the good old days of my college days with console based SMTP clients such as elm and pine… as I recall these clients showed progress via a simple ASCII spiner.

I was impressed with how simple this is to do with .NET Framework 2.0.. I started off writing the usage code I wanted to enable, then built a simple class that meet those requirements.. I highly recommend this process especially for more complex designs.
Here is the client code: 

        static void Main(string[] args)
{
ConsoleSpiner spin = new ConsoleSpiner();
Console.Write("Working....");
while (true)
{
spin.Turn();
            }
}

And here is the class I came up with.

    public class ConsoleSpiner
{
int counter;
public ConsoleSpiner()
{
counter = 0;
        }
public void Turn()
{
counter++;
switch (counter % 4)
{
case 0: Console.Write("/"); break;
case 1: Console.Write("-"); break;
case 2: Console.Write("\\"); break;
case 3: Console.Write("-"); break;
            }
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
        }
}

PS – does anyone still use elm\pine? Are their clients that work with exchange? Also, I was always told that pine was an acronym for “Pine Is Not Elm”, but accounting to the official site it is not.

Comments

  • Anonymous
    June 11, 2005
    The comment has been removed

  • Anonymous
    June 11, 2005
    WOW! Look at that spinner spin!

  • Anonymous
    June 11, 2005
    I'm not buying this one Brad.

    You need to make time the spinner based on milliseconds since last turn... you can't just turn it on every call. It's like an old videogame running as fast as it can instead of using the clock to make sure it runs at the same speed on any CPU.

    I would fix it for you but I am too busy.

  • Anonymous
    June 11, 2005
    Pine is still used (and developed) at the UW.

    It's still the premier IMAP client out there (it does IMAP better than all the others IMHO).

    It's a bit klunky but it DOES show what the protocol can do.

  • Anonymous
    June 11, 2005
    Btw, from the project history:
    With Pine 3.90, significant new functionality has been added, notably aggregate operations for manipulating groups of messages at once, the first (alpha) release of PC-Pine for the Winsock network interface standard, and greatly improved Usenet (News) support. One of the early interpretations of the name "Pine" was "Pine Is No-longer Elm"; today a "Program for Internet News and Email" seems more apropos. Laurence Lundblade (Pine author emeritus) has more insight into the issue of what "Pine" really stands for.


    So Pine DOES stand for "Pine is not Elm". Just like FINE is "FINE is not Emacs" etc.

  • Anonymous
    June 11, 2005
    The comment has been removed

  • Anonymous
    June 11, 2005
    I have a question about your style. I used to initialize every variable on the declaration. Every single one. Until the day I adopted FXCop and it suggested not initializing a variable to its default value. Can you elaborate on this rule?

    Btw, my version (also since college days) is a little more 'ANSI', I would use 'Console.Write("b");' instead of SetCursorPosition-fancy-thing :)

    --Leo

  • Anonymous
    June 11, 2005
    BTW I thing the characters |/- make a better spinner than /--.

  • Anonymous
    June 11, 2005
    I used pine last session at a university :) Don't know if it works with Exchange, I assume they used some *NIX-mailserver there.

  • Anonymous
    June 12, 2005
    For the record, running this code in the debugger causes an IOException to be thrown...maybe due to VS trapping the output of the app in its own console?

  • Anonymous
    June 12, 2005
    Judah, sorry about the exception you are seeing… This is actually a result of a “feature” of VS called Quick Console which is intended to replace the system console allowing for a better developer experience dealing with console output. Unfortunately, Quick Console doesn’t support many console features (such as SetCursorPosition, ConsoleColor, etc). Regrettably, it fails in a difficult to understand way… you get an IOException which could lead developers to believe it is a bug in their code when it is really a bug.. ahh, I mean feature of VS.

    As such, it is my advice that you turn off this “feature” on all console applications… Luckily it is pretty easy to do:
    Tools->Options->Debugging->General – “Redirect all console output to Quick Console window”

  • Anonymous
    June 12, 2005
    Brad,

    Small spelling correction: "Spiner" should be "spinner"

    Personally, I prefer my spinning characters to be: |, /, -, , |, /, -, . It's a bit smoother :)

    HTH.

  • Anonymous
    June 12, 2005
    This Whidbey SetCursorPosition stuff is not implemented in .NET 1.x.

    To make progress version-independent I use "r" char. Pseudo-code:

    Console.Write("rWorking: " + <indicator> );

  • Anonymous
    June 12, 2005
    And the most clean and user-friendly case is:

    DateTime nextDump = DateTime.Now;
    for( ... )
    {
    // working

    if( DateTime.Now>=nextDump )
    {
    Console.Write("rFormatting: "+percent+"%...");
    nextDump = DateTime.Now.AddSecond(0.2);
    }
    }

    Spinner is not great, user likes to see what amount of work done. Also, you should not update console too fast, because it is exceptionally slow operation.

  • Anonymous
    June 13, 2005
    "I started off writing the usage code I wanted to enable, then built a simple class that meet those requirements.".... or if you are into the latest buzzwords it's called Test Driven Development. :-)

  • Anonymous
    June 13, 2005
    "Tools->Options->Debugging->General – Redirect all console output to Quick Console window"

    I don't have this option. Is this only available in VS 2005?

  • Anonymous
    June 13, 2005
    Yes, Quick Console is a VS2005 feature...

  • Anonymous
    June 13, 2005
    It would be better to disable QuickConsole by default, for better backward compatibility.

    When I start with new Console Project in VS2005 I often in doubt, where my WriteLines gone?

    At least VS team should apply white-on-black colors to this tool window to make it visually equals to standalone console.

  • Anonymous
    June 13, 2005
    Thanks Brad. I did this once, but used the Title bar to show the spinner. Then the status does not get mixed up with other ouput and you don't need to use position or backspace, etc. You could also use "|" bars to show a console-progress bar deal. Cheers.

  • Anonymous
    June 13, 2005
    People use Mutt nowadays and only corporations use Exchange, everyone else uses IMAP for server-side email systems.

    Novell's Evolution mail client can connect to Exchange, but it's a GUI application.

  • Anonymous
    June 13, 2005
    Nice spinner :)

    I blogged about this a while back, but to your question on Pine clients, Andrew Troelsen wrote a C# "Pine" client for an article on Programming Outlook 2003 using C#.

    http://blogs.msdn.com/danielfe/archive/2004/06/07/150625.aspx

  • Anonymous
    June 14, 2005
    I can only hope no one else will consider this approach usefull.

  • Anonymous
    June 15, 2005
    I read Brad Abrams post on Showing Progress in a Console Window. I did not like the way he implemented...

  • Anonymous
    July 09, 2005
    Brad, why do you do a counter = 0 in the constructor?

    I have no problem with explicitly declaring the default constructor (you talked about that in your guidelines ;) but a managed System.Int32 is always 0 when the object is constructed.

    So what's the deal? :)

  • Anonymous
    July 10, 2005
    The comment has been removed

  • Anonymous
    May 31, 2009
    PingBack from http://woodtvstand.info/story.php?id=1342

  • Anonymous
    June 13, 2009
    PingBack from http://barstoolsite.info/story.php?id=613