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 removedAnonymous
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 removedAnonymous
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 :)
--LeoAnonymous
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.aspxAnonymous
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 removedAnonymous
May 31, 2009
PingBack from http://woodtvstand.info/story.php?id=1342Anonymous
June 13, 2009
PingBack from http://barstoolsite.info/story.php?id=613