Avete un fantastico software che viene eseguito in console mode ??

Avete necessità di dotarlo di una progress bar per farlo sembrare "più figo" ??

Per quanto possa essere figa una Console App ovviamente......

Allora questo post fa per Voi !

Recentemente mi trovavo in una situazione simile, e dopo aver ricercato in rete ho trovato la seguente soluzione, elegante ed efficace, che desidero condividere con Voi.

Infatti è inutile inventarsi soluzioni esotiche e/o personalizzate: affidatevi senza timore al pacchetto NuGet ShellProgressBar: è semplice, gratuito (MIT License) e funziona perfettamente.

Vi assicuro di non centrare assolutamente nulla con l'autore del software oggetto di questo scritto (tra l'altro gratuito): semplicemente è un buona soluzione che intendo condividere.

Sono certo che in giro si trovano altre soluzione molto più articolate, ma questa che presente è realmente semplice e ritengo più che soddisfacente per la maggior parte degli usi.

 Nel seguito Vi presento uno snippet per poterlo usare in modo efficare.

using ShellProgressBar;
using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var maxTicks = 9000;
            using (var pbar = new ProgressBar(maxTicks, "Starting", ConsoleColor.Cyan))
            {
                for (var i = 0; i < maxTicks; i++)
                {
                    pbar.Tick("Currently processing " + i);
                }
            }
        }
    }
}

Il valore maxTicks rappresenta il max valore possibile: ad ogni iterazione la barra avanza e propone la relativa percentuale.Usando il metodo Tick è possibile passare il valore attuale nonchè un messaggio: la figura è abbastanza esplicativa.

La cosa divertente è che è possibile creare una sottobarra, che tiene conto della progressione di sotto task. Anche in questo caso l'immagine di seguito è abbasta esplicativa: un task principale (progress bas blu) che è costituita da diversi sotto task (progress bar verde).

Ecco lo snippet per ottenere quanto sopra.

using ShellProgressBar;
using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {http://www.informaticapressapochista.com/it/administrator/#
            var maxTicks = 9000;
            using (var pbar = new ProgressBar(maxTicks, "Starting", ConsoleColor.Cyan))
            {
                for (var i = 0; i < maxTicks; i++)
                {
                    pbar.Tick("Currently processing " + i);

                    int ticksottopbar = 10;

                    var sottopbar = pbar.Spawn(ticksottopbar, "Child Progress Bar");
                    for (var a = 0; a < ticksottopbar; a++)
                    {
                        sottopbar.Tick("Valore Child ProgressBar");
                    }
                }
            }

        }
    }
}

Abbastanza esplicativo, no ?? Quello di cui difetta, secondo me, è la presenza di una ETA (= Estimated time of arrival), cioè una stima del tempo che occorre per terminare l'operazione.

Ecco nel seguito una semplicissima implementazione che permette di ottenere anche il valore ETA.

using ShellProgressBar;
using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var maxTicks = 9000;
            using (var pbar = new ProgressBar(maxTicks, "Starting", ConsoleColor.Cyan))
            {
                DateTime m_DataOraStart = DateTime.Now;
                

                for (var i = 0; i < maxTicks; i++)
                {
                    pbar.Tick("Currently processing " + i + " ETA: " + CalcolaETA(m_DataOraStart, maxTicks,i));

                    int ticksottopbar = 10;

                    var sottopbar = pbar.Spawn(ticksottopbar, "Child Progress Bar");
                    for (var a = 0; a < ticksottopbar; a++)
                    {
                        sottopbar.Tick("Valore Child ProgressBar");

                    }
                }
            }

        }

        private static string CalcolaETA(DateTime _DataOraInizio, int _TickTot, int _TickAttuale)
        {
            if (_TickAttuale <= 0)
                return "-- %";

            TimeSpan tsDiff=DateTime.Now.Subtract(_DataOraInizio);
            int SecAllaFine = (int)((tsDiff.TotalSeconds / _TickAttuale) * _TickTot);
            TimeSpan t = TimeSpan.FromSeconds(SecAllaFine);

            return string.Format("{0:D2}h:{1:D2}m:{2:D2}s",
                t.Hours,
                t.Minutes,
                t.Seconds);
        }


    }
}

Spero Vi possa essere utile

Linkografia

Shellprogressbar on GitHub by Mpdreamz