简单版

1
2
3
4
5
6
static string ProgressBar(double value,int size = 10)
{
int block = (int)(value * size);
string text = $"{value:P} [{new string('■', block)}{new string('□', size - block)}]";
return text;
}
⇧看看就行,没啥用⇧
1
2
3
4
5
6
7
8
9
10
Console.Write("Performing some task... ");
using (var progress = new ProgressBar())
{
for (int i = 0; i <= 100; i++)
{
progress.Report((double)i / 100);
Thread.Sleep(20);
}
}
Console.WriteLine("Done.");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class ProgressBar : IDisposable, IProgress<double>
{
private const int blockCount = 10;
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
private const string animation = @"|/-\";

private readonly Timer timer;

private double currentProgress = 0;
private string currentText = string.Empty;
private bool disposed = false;
private int animationIndex = 0;

public ProgressBar()
{
timer = new Timer(TimerHandler);
if (!Console.IsOutputRedirected)
ResetTimer();
}

public void Report(double value)
{
value = Math.Max(0, Math.Min(1, value));
Interlocked.Exchange(ref currentProgress, value);
}

private void TimerHandler(object state)
{
lock (timer)
{
if (disposed) return;
int progressBlockCount = (int)(currentProgress * blockCount);
int percent = (int)(currentProgress * 100);
string text = string.Format("[{0}{1}] {2,3}% {3}",
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
percent,
animation[animationIndex++ % animation.Length]);
UpdateText(text);
ResetTimer();
}
}

private void UpdateText(string text)
{
int commonPrefixLength = 0;
int commonLength = Math.Min(currentText.Length, text.Length);
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
commonPrefixLength++;
StringBuilder outputBuilder = new StringBuilder();
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
outputBuilder.Append(text.Substring(commonPrefixLength));
int overlapCount = currentText.Length - text.Length;
if (overlapCount > 0)
{
outputBuilder.Append(' ', overlapCount);
outputBuilder.Append('\b', overlapCount);
}
Console.Write(outputBuilder);
currentText = text;
}

private void ResetTimer()
{
timer.Change(animationInterval, TimeSpan.FromMilliseconds(-1));
}

public void Dispose()
{
lock (timer)
{
disposed = true;
UpdateText(string.Empty);
}
}
}

https://gist.github.com/DanielSWolf/0ab6a96899cc5377bf54