提问人:sandy 提问时间:4/21/2023 最后编辑:Theodor Zouliassandy 更新时间:4/21/2023 访问量:323
尝试异步显示进度条,但进度条覆盖了以前的 C# 控制台应用程序
Trying to show Progress Bar with asynchronously, but progress bar override the previous C# console application
问:
public class test
{
private static readonly object _lock = new object();
public static async Task DrawProgressBar(int complete, int maxVal, int barSize,
char progressCharacter)
{
lock (_lock)
{
Console.CursorVisible = false;
int left = Console.CursorLeft;
decimal perc = (decimal)complete / (decimal)maxVal;
int chars = (int)Math.Floor(perc / ((decimal)1 / (decimal)barSize));
string p1 = String.Empty, p2 = String.Empty;
for (int i = 0; i < chars; i++) p1 += progressCharacter;
for (int i = 0; i < barSize - chars; i++) p2 += progressCharacter;
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(p1);
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write(p2);
Console.ResetColor();
Console.Write(" {0}%", (perc * 100).ToString("N2"));
Console.CursorLeft = left;
}
}
public static async Task Main()
{
string[] files = new string[] { "file1.txt", "file2.txt", "file3.txt" };
var tasks = new List<Task>();
for (int i = 0; i < files.Length; i++)
{
Console.SetCursorPosition((1 * i), 2 * i);
Console.WriteLine("Processing file {0} of {1}: {2}",
i + 1, files.Length, files[i]);
Task t = Task.Run(() => { Download(); });
tasks.Add(t);
}
await Task.WhenAll(tasks);
Console.WriteLine();
}
private static async Task Download()
{
for (int j = 0; j <= 100 - 1; j++)
{
DrawProgressBar(j , 100, 50, '=');
System.Threading.Thread.Sleep(100);
}
}
}
可以错过一些我错过的点。
答:
1赞
Frenchy
4/21/2023
#1
按照不同的建议,我刚刚编写了这段代码,似乎还可以。
我认为使用更好......IAsyncEnumerable
static private readonly object _sync = new object();
static async Task Main(string[] args)
{
var colors = new List<Enum>
{
ConsoleColor.DarkBlue,ConsoleColor.Red, ConsoleColor.Yellow,
ConsoleColor.Green, ConsoleColor.DarkGray, ConsoleColor.Blue
};
char[] symbol = new char[] { '#', '\u25A0', '\u2592', '\u2588', '\u2551', '\u2502' };
var min = 0;
var max = 100;
var tasks = Enumerable.Range(0, 6).Select(async p =>
{
await foreach (var i in DoJob(p))
{
Update(i, (p + 1) * 3, min, max, colors[p], symbol[p]);
}
});
await Task.WhenAll(tasks);
Console.Read();
}
private static async IAsyncEnumerable<int> DoJob(int p)
{
for (int i = 0; i <= 100; i++)
{
await Task.Delay(50 + p * 25);//Simulate waiting for data to come through.
yield return i;
}
}
private static void Update(int value, int row, int min, int max, Enum _color, char symbol)
{
// Calculate the percentage complete
var percentComplete = (double)(value - min) / (max - min);
// Calculate the width of the progress bar
var width = Console.WindowWidth - 10;
var progressWidth = (int)(percentComplete * width);
lock (_sync)
{
// Set the cursor position and color
Console.SetCursorPosition(0, row);
Console.ForegroundColor = (ConsoleColor)_color;
// Write the progress bar
Console.Write("[{0}{1}] {2:P0}", new string(symbol, progressWidth), new string(' ', width - progressWidth), percentComplete);
// Reset the color
Console.ResetColor();
}
}
评论
DrawProgressBar
Download
async
await