Scott Hanselman

Accelerated 3D VR, sure, but impress me with a nice ASCII progress bar or spinner

December 04, 2017 Comment on this post [11] Posted in DotNetCore
Sponsored By

I'm glad you have a 1080p 60fps accelerated graphics setup, but I'm old school. Impress me with a really nice polished ASCII progress bar or spinner!

I received two tips this week about cool .NET Core ready progress bars so I thought I'd try them out.

ShellProgressBar by Martijn Laarman

This one is super cool. It even supports child progress bars for async stuff happening in parallel! It's very easy to use. I was able to get a nice looking progress bar going in minutes.

static void Main(string[] args)
{
const int totalTicks = 100;
var options = new ProgressBarOptions
{
ForegroundColor = ConsoleColor.Yellow,
ForegroundColorDone = ConsoleColor.DarkGreen,
BackgroundColor = ConsoleColor.DarkGray,
BackgroundCharacter = '\u2593'
};
using (var pbar = new ProgressBar(totalTicks, "Initial message", options))
{
pbar.Tick(); //will advance pbar to 1 out of 10.
//we can also advance and update the progressbar text
pbar.Tick("Step 2 of 10");
TickToCompletion(pbar, totalTicks, sleep: 50);
}
}

Boom.

Cool ASCII Progress Bars in .NET Core

Be sure to check out the examples for ShellProgressBar, specifically ExampleBase.cs where he has some helper stuff like TickToCompletion() that isn't initially obvious.

Kurukuru by Mayuki Sawatari

Another nice progress system that is in active development for .NET Core (like super active...I can see they updated code an hour ago!) is called Kurukuru. This code is less about progress bars and more about spinners. It's smart about Unicode vs. non-Unicode as there's a lot of cool characters you could use in a Unicode-aware console that make for attractive spinners.

What a lovely ASCII Spinner in .NET Core!

Kurukuru is also super easy to use and integrated into your code. It also uses the "using" disposable pattern in a clever way. Wrap your work and if you throw an exception, it will show a failed spinner.

Spinner.Start("Processing...", () =>
{
Thread.Sleep(1000 * 3);

// MEMO: If you want to show as failed, throw a exception here.
// throw new Exception("Something went wrong!");
});

Spinner.Start("Stage 1...", spinner =>
{
Thread.Sleep(1000 * 3);
spinner.Text = "Stage 2...";
Thread.Sleep(1000 * 3);
spinner.Fail("Something went wrong!");
});

TIP: If your .NET Core console app wants to use an async Main (like I did) and call Kurukuru's async methods, you'll want to indicate you want to use the latest C# 7.1 features by adding this to your project's *.csproj file:

<PropertyGroup>
    <LangVersion>latest</LangVersion>
</PropertyGroup>

This allowed me to do this:

public static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
await Spinner.StartAsync("Stage 1...", async spinner =>
{
await Task.Delay(1000 * 3);
spinner.Text = "Stage 2...";
await Task.Delay(1000 * 3);
spinner.Fail("Something went wrong!");
});
}

Did I miss some? I'm sure I did. What nice ASCII progress bars and spinners make YOU happy?

And again, as with all Open Source, I encourage you to HELP OUT! I know the authors would appreciate it.


Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
December 04, 2017 12:25
Nice jobs both! Blog10
December 04, 2017 12:37
Maybe someone should try to port Ora to dotnet. Beautiful, but node.
December 04, 2017 12:47
Shout out about Colorful.Console which lets you add some colour to your console apps and use cool ASCII art using Figlet fonts (ASCII fonts).
December 04, 2017 18:52
If you use something like ConEmu instead of the Windows shell the results will be much nicer.
December 04, 2017 21:34
I had to write a command-line utility to perform a long-running but variable-length task, and needed to add some sort of asynchronous progress spinner to let the user know the command was still actively working and the machine wasn't frozen. I came up with a pattern that I figured was hypnotic enough to keep the user distracted, but while I originally called it a "Hypnotic sparkle-bob", it ended up being called the "throbber":
°º¤ø,¸,ø¤º°`


Next time, though, I'd probably turn to Kurukuru.
December 04, 2017 23:15
I wrote a one-line Powershell countdown timer for inserting a short pause without requiring a keystroke, for when something is about to happen and you want to briefly show output from the last commmand:

for([int] $i=3;$i -gt 0;$i--){Write-Host "$i" -NoNewline ;Start-Sleep 1; Write-Host ("`r" * ([string] $i).Length) -NoNewline }


It's not fancy ascii but it acts like the spinner example - overwriting the previously displayed number.
December 05, 2017 5:41
border-radius: 2px; doesn't work on the progress bar. Fail!
December 08, 2017 3:39
ASCII spinners really take me back to my childhood with the family Apple //c!
December 12, 2017 12:12
December 12, 2017 12:55
These are for .NET core. There must be loads for .NET Framework? Any pointers?
December 14, 2017 12:56
@Matt Frear - They are both .NET Standard, so they will work with the "old" .NET framework. ShellProgressbar is .NET Standard 1.3 and Kurukuru is .NET Standard 2.0.

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.