简单版
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; }
Click
⇧看看就行,没啥用⇧
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