diff --git a/build.bat b/build.bat
index 094a0ff..4c984ad 100644
--- a/build.bat
+++ b/build.bat
@@ -1,2 +1,2 @@
-"C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ^
+"C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe" ^
build\Build.proj /p:NuspecFile=build\ShellProgressBar.nuspec;BUILD_NUMBER=%1 /t:NugetPackage
\ No newline at end of file
diff --git a/build/Build.proj b/build/Build.proj
index 277fa3f..6aa2816 100644
--- a/build/Build.proj
+++ b/build/Build.proj
@@ -33,7 +33,7 @@
AssemblyVersion="$(Version)"
AssemblyFileVersion="$(Version)"/>
-
+
diff --git a/src/ShellProgressBar.Example/Examples/DeeplyNestedProgressBarTreeExample.cs b/src/ShellProgressBar.Example/Examples/DeeplyNestedProgressBarTreeExample.cs
new file mode 100644
index 0000000..398a17c
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/DeeplyNestedProgressBarTreeExample.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class DeeplyNestedProgressBarTreeExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var random = new Random();
+
+ var numberOfSteps = 7;
+
+ var overProgressOptions = new ProgressBarOptions
+ {
+ BackgroundColor = ConsoleColor.DarkGray,
+ };
+
+ using (var pbar = new ProgressBar(numberOfSteps, "overal progress", overProgressOptions))
+ {
+ var stepBarOptions = new ProgressBarOptions
+ {
+ ForeGroundColor = ConsoleColor.Cyan,
+ ForeGroundColorDone = ConsoleColor.DarkGreen,
+ ProgressCharacter = '─',
+ BackgroundColor = ConsoleColor.DarkGray,
+ CollapseWhenFinished = false,
+
+ } ;
+ Parallel.For(0, numberOfSteps, (i) =>
+ {
+ var workBarOptions = new ProgressBarOptions
+ {
+ ForeGroundColor = ConsoleColor.Yellow,
+ ProgressCharacter = '─',
+ BackgroundColor = ConsoleColor.DarkGray,
+ };
+ var childSteps = random.Next(1, 5);
+ using (var childProgress = pbar.Spawn(childSteps, $"step {i} progress", stepBarOptions))
+ Parallel.For(0, childSteps, (ci) =>
+ {
+ var childTicks = random.Next(50, 250);
+ using (var innerChildProgress = childProgress.Spawn(childTicks, $"step {i}::{ci} progress", workBarOptions))
+ {
+ for (var r = 0; r < childTicks; r++)
+ {
+ innerChildProgress.Tick();
+ Program.BusyWait(50);
+ }
+ }
+ childProgress.Tick();
+ });
+
+ pbar.Tick();
+ });
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/DrawsOnlyOnTickExample.cs b/src/ShellProgressBar.Example/Examples/DrawsOnlyOnTickExample.cs
new file mode 100644
index 0000000..734f19b
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/DrawsOnlyOnTickExample.cs
@@ -0,0 +1,23 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class DrawsOnlyOnTickExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 5;
+ var updateOnTicksOnlyOptions = new ProgressBarOptions {DisplayTimeInRealTime = false};
+ using (var pbar = new ProgressBar(ticks, "only update time on ticks", updateOnTicksOnlyOptions))
+ {
+ for (var i = 0; i < ticks; i++)
+ {
+ pbar.Tick("only update time on ticks, current: " + i);
+ Thread.Sleep(1750);
+ }
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/LongRunningExample.cs b/src/ShellProgressBar.Example/Examples/LongRunningExample.cs
new file mode 100644
index 0000000..18f0efa
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/LongRunningExample.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class LongRunningExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 100;
+ using (var pbar = new ProgressBar(ticks, "my long running operation", ConsoleColor.Green))
+ {
+ for (var i = 0; i < ticks; i++)
+ {
+ pbar.Tick("step " + i);
+ Thread.Sleep(50);
+ }
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/NegativeMaxTicksExample.cs b/src/ShellProgressBar.Example/Examples/NegativeMaxTicksExample.cs
new file mode 100644
index 0000000..0f8df1d
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/NegativeMaxTicksExample.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class NegativeMaxTicksExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = -100;
+ using (var pbar = new ProgressBar(ticks, "my operation with negative ticks", ConsoleColor.Cyan))
+ {
+ for (var i = 0; i < ticks; i++)
+ {
+ pbar.Tick("step " + i);
+ Thread.Sleep(50);
+ }
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/NestedProgressBarPerStepProgress.cs b/src/ShellProgressBar.Example/Examples/NestedProgressBarPerStepProgress.cs
new file mode 100644
index 0000000..f5b0e0a
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/NestedProgressBarPerStepProgress.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class NestedProgressBarPerStepProgress : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var outerTicks = 10;
+ using (var pbar = new ProgressBar(outerTicks, "outer progress", ConsoleColor.Cyan))
+ {
+ for (var i = 0; i < outerTicks; i++)
+ {
+ InnerProgressBars(pbar);
+ pbar.Tick();
+ }
+ }
+ return Task.FromResult(1);
+ }
+
+ private static void InnerProgressBars(ProgressBar pbar)
+ {
+ var innerProgressBars = Enumerable.Range(0, new Random().Next(2, 6))
+ .Select(s => pbar.Spawn(new Random().Next(2, 5), $"inner bar {s}"))
+ .ToList();
+
+ var maxTicks = innerProgressBars.Max(p => p.MaxTicks);
+
+ for (var ii = 0; ii < maxTicks; ii++)
+ {
+ foreach (var p in innerProgressBars)
+ {
+ InnerInnerProgressBars(p);
+ p.Tick();
+ }
+
+
+ Thread.Sleep(4);
+ }
+ foreach (var p in innerProgressBars) p.Dispose();
+ }
+
+ private static void InnerInnerProgressBars(ChildProgressBar pbar)
+ {
+ var progressBarOption = new ProgressBarOptions { ForeGroundColor = ConsoleColor.Yellow };
+ var innerProgressBars = Enumerable.Range(0, new Random().Next(1, 3))
+ .Select(s => pbar.Spawn(new Random().Next(5, 10), $"inner bar {s}", progressBarOption))
+ .ToList();
+ if (!innerProgressBars.Any()) return;
+
+ var maxTicks = innerProgressBars.Max(p => p.MaxTicks);
+
+ for (var ii = 0; ii < maxTicks; ii++)
+ {
+ foreach (var p in innerProgressBars)
+ p.Tick();
+ }
+ foreach (var p in innerProgressBars) p.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/NeverCompletesExample.cs b/src/ShellProgressBar.Example/Examples/NeverCompletesExample.cs
new file mode 100644
index 0000000..6c21404
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/NeverCompletesExample.cs
@@ -0,0 +1,21 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class NeverCompletesExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 5;
+ using (var pbar = new ProgressBar(ticks, "A console progress bar does not complete"))
+ {
+ pbar.Tick();
+ pbar.Tick();
+ pbar.Tick();
+ pbar.Tick();
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/NeverTicksExample.cs b/src/ShellProgressBar.Example/Examples/NeverTicksExample.cs
new file mode 100644
index 0000000..a45acfa
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/NeverTicksExample.cs
@@ -0,0 +1,17 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class NeverTicksExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 10;
+ using (var pbar = new ProgressBar(ticks, "A console progress bar that never ticks"))
+ {
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/ThreadedTicksOverflowExample.cs b/src/ShellProgressBar.Example/Examples/ThreadedTicksOverflowExample.cs
new file mode 100644
index 0000000..1a602e2
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/ThreadedTicksOverflowExample.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class ThreadedTicksOverflowExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 200;
+ using (var pbar = new ProgressBar(ticks/10, "My operation that ticks to often using threads", ConsoleColor.Cyan))
+ {
+ var threads = Enumerable.Range(0, ticks).Select(i => new Thread(() => pbar.Tick("threaded tick " + i))).ToList();
+ foreach (var thread in threads) thread.Start();
+ foreach (var thread in threads) thread.Join();
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/TicksOverflowExample.cs b/src/ShellProgressBar.Example/Examples/TicksOverflowExample.cs
new file mode 100644
index 0000000..a3d6c2c
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/TicksOverflowExample.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class TicksOverflowExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 10;
+ using (var pbar = new ProgressBar(ticks, "My operation that ticks to often", ConsoleColor.Cyan))
+ {
+ for (var i = 0; i < ticks*10; i++)
+ {
+ pbar.Tick("too many steps " + i);
+ Thread.Sleep(50);
+ }
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/UpdatesMaxTicksExample.cs b/src/ShellProgressBar.Example/Examples/UpdatesMaxTicksExample.cs
new file mode 100644
index 0000000..8d022c3
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/UpdatesMaxTicksExample.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class UpdatesMaxTicksExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 10;
+ using (var pbar = new ProgressBar(ticks, "My operation that updates maxTicks", ConsoleColor.Cyan))
+ {
+ var sleep = 1000;
+ for (var i = 0; i < ticks; i++)
+ {
+ pbar.Tick("Updating maximum ticks " + i);
+ if (i == 5)
+ {
+ ticks = 120;
+ pbar.UpdateMaxTicks(ticks);
+ sleep = 50;
+ }
+ Thread.Sleep(sleep);
+ }
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Examples/ZeroMaxTicksExample.cs b/src/ShellProgressBar.Example/Examples/ZeroMaxTicksExample.cs
new file mode 100644
index 0000000..184c7ef
--- /dev/null
+++ b/src/ShellProgressBar.Example/Examples/ZeroMaxTicksExample.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example.Examples
+{
+ public class ZeroMaxTicksExample : IProgressBarExample
+ {
+ public Task Start(CancellationToken token)
+ {
+ var ticks = 0;
+ using (var pbar = new ProgressBar(ticks, "my operation with zero ticks", ConsoleColor.Cyan))
+ {
+ for (var i = 0; i < ticks; i++)
+ {
+ pbar.Tick("step " + i);
+ Thread.Sleep(50);
+ }
+ }
+ return Task.FromResult(1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/IProgressBarExample.cs b/src/ShellProgressBar.Example/IProgressBarExample.cs
new file mode 100644
index 0000000..297b7ea
--- /dev/null
+++ b/src/ShellProgressBar.Example/IProgressBarExample.cs
@@ -0,0 +1,10 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ShellProgressBar.Example
+{
+ public interface IProgressBarExample
+ {
+ Task Start(CancellationToken token);
+ }
+}
\ No newline at end of file
diff --git a/src/ShellProgressBar.Example/Program.cs b/src/ShellProgressBar.Example/Program.cs
index 1274b9a..cfaceb5 100644
--- a/src/ShellProgressBar.Example/Program.cs
+++ b/src/ShellProgressBar.Example/Program.cs
@@ -1,71 +1,64 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using ShellProgressBar.Example.Examples;
namespace ShellProgressBar.Example
{
class Program
{
+ private static readonly IList ExampleProgressBars = new List
+ {
+ new DeeplyNestedProgressBarTreeExample(),
+ new NestedProgressBarPerStepProgress(),
+ new DrawsOnlyOnTickExample(),
+ new ThreadedTicksOverflowExample(),
+ new TicksOverflowExample(),
+ new NegativeMaxTicksExample(),
+ new ZeroMaxTicksExample(),
+ new LongRunningExample(),
+ new NeverCompletesExample(),
+ new UpdatesMaxTicksExample(),
+ new NeverTicksExample(),
+ };
+
static void Main(string[] args)
{
- var ticks = 10;
- using (var pbar = new ProgressBar(ticks, "A console progress bar that never ticks"))
- {
- }
- using (var pbar = new ProgressBar(ticks, "A console progress bar does not complete"))
- {
- pbar.Tick();
- pbar.Tick();
- pbar.Tick();
- pbar.Tick();
- }
- ticks = 100;
- using (var pbar = new ProgressBar(ticks, "my long running operation", ConsoleColor.Green))
- {
- for (var i = 0; i < ticks; i++)
- {
- pbar.Tick("step " + i);
- Thread.Sleep(50);
- }
- }
- ticks = 0;
- using (var pbar = new ProgressBar(ticks, "my operation with zero ticks", ConsoleColor.Cyan))
- {
- for (var i = 0; i < ticks; i++)
- {
- pbar.Tick("step " + i);
- Thread.Sleep(50);
- }
- }
- ticks = -100;
- using (var pbar = new ProgressBar(ticks, "my operation with negative ticks", ConsoleColor.Cyan))
- {
- for (var i = 0; i < ticks; i++)
- {
- pbar.Tick("step " + i);
- Thread.Sleep(50);
- }
- }
- ticks = 10;
- using (var pbar = new ProgressBar(ticks, "My operation that ticks to often", ConsoleColor.Cyan))
+ Console.WindowWidth = Console.LargestWindowWidth / 2;
+ Console.WindowHeight = Console.LargestWindowHeight / 3;
+
+ var cts = new CancellationTokenSource();
+
+ Console.CancelKeyPress += (s, e) =>
{
- for (var i = 0; i < ticks * 10; i++)
- {
- pbar.Tick("too many steps " + i);
- Thread.Sleep(50);
- }
- }
- ticks = 200;
- using (var pbar = new ProgressBar(ticks / 10, "My operation that ticks to often using threads", ConsoleColor.Cyan))
+ e.Cancel = true;
+ cts.Cancel();
+ };
+
+ MainAsync(args, cts.Token).GetAwaiter().GetResult();
+ }
+
+ static async Task MainAsync(string[] args, CancellationToken token)
+ {
+ foreach (var example in ExampleProgressBars)
{
- var threads = Enumerable.Range(0, ticks).Select(i => new Thread(() => pbar.Tick("threaded tick " + i))).ToList();
- foreach (var thread in threads) thread.Start();
- foreach (var thread in threads) thread.Join();
+ await example.Start(token);
+ Console.Clear();
}
+
Console.ReadLine();
}
+ public static void BusyWait(int milliseconds)
+ {
+ var sw = Stopwatch.StartNew();
+
+ while (sw.ElapsedMilliseconds < milliseconds)
+ Thread.SpinWait(1000);
+ }
+
}
}
diff --git a/src/ShellProgressBar.Example/ShellProgressBar.Example.csproj b/src/ShellProgressBar.Example/ShellProgressBar.Example.csproj
index a428070..79fda04 100644
--- a/src/ShellProgressBar.Example/ShellProgressBar.Example.csproj
+++ b/src/ShellProgressBar.Example/ShellProgressBar.Example.csproj
@@ -42,8 +42,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -54,6 +66,7 @@
ShellProgressBar
+