我如何更新C#Windows控制台应用程序中的当前行?
在C#中构建Windows控制台应用程序时,是否可以写入控制台而无需扩展当前行或转至新行? 例如,如果我想显示一个百分比来表示一个进程完成的距离,我只想更新与游标在同一行上的值,而不必将每个百分比都放在一个新行上。
这可以通过“标准”C#控制台应用程序完成吗?
如果您仅在控制台上打印"r"
,则光标会返回到当前行的开头,然后您可以重写它。 这应该可以做到这一点:
for(int i = 0; i < 100; ++i)
{
Console.Write("r{0}% ", i);
}
注意数字后面的几个空格,以确保之前的内容被删除。
另外请注意使用Write()
而不是WriteLine()
因为您不想在行尾添加“ n”。
您可以使用Console.SetCursorPosition
设置光标位置,然后在当前位置写入。
这是一个显示简单的“微调”的例子:
static void Main(string[] args)
{
var spin = new ConsoleSpinner();
Console.Write("Working....");
while (true)
{
spin.Turn();
}
}
public class ConsoleSpinner
{
int counter;
public void Turn()
{
counter++;
switch (counter % 4)
{
case 0: Console.Write("/"); counter = 0; break;
case 1: Console.Write("-"); break;
case 2: Console.Write(""); break;
case 3: Console.Write("|"); break;
}
Thread.Sleep(100);
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
}
请注意,您必须确保使用新的输出或空白覆盖任何现有的输出。
更新:由于有人批评该示例仅将光标移回一个字符,我将添加以澄清:使用SetCursorPosition
可以将光标设置到控制台窗口中的任何位置。
Console.SetCursorPosition(0, Console.CursorTop);
将光标设置到当前行的开头(或者可以直接使用Console.CursorLeft = 0
)。
到目前为止,我们有三个相互竞争的方法来解决这个问题:
Console.Write("r{0} ", value); // Option 1: carriage return
Console.Write("bbbbb{0}", value); // Option 2: backspace
{ // Option 3 in two parts:
Console.SetCursorPosition(0, Console.CursorTop); // - Move cursor
Console.Write(value); // - Rewrite
}
我一直使用Console.CursorLeft = 0
,这是第三个选项的变体,所以我决定做一些测试。 以下是我使用的代码:
public static void CursorTest()
{
int testsize = 1000000;
Console.WriteLine("Testing cursor position");
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < testsize; i++)
{
Console.Write("rCounting: {0} ", i);
}
sw.Stop();
Console.WriteLine("nTime using r: {0}", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
int top = Console.CursorTop;
for (int i = 0; i < testsize; i++)
{
Console.SetCursorPosition(0, top);
Console.Write("Counting: {0} ", i);
}
sw.Stop();
Console.WriteLine("nTime using CursorLeft: {0}", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
Console.Write("Counting: ");
for (int i = 0; i < testsize; i++)
{
Console.Write("bbbbbbbb{0,8}", i);
}
sw.Stop();
Console.WriteLine("nTime using b: {0}", sw.ElapsedMilliseconds);
}
在我的机器上,我得到以下结果:
另外, SetCursorPosition
引起了明显的闪烁,我没有观察到任何一种选择。 所以,道德是尽可能使用退后或回车 , 谢谢教我更快的方式来做到这一点,所以!
更新 :在注释中,Joel建议SetCursorPosition在移动距离方面是恒定的,而其他方法是线性的。 进一步的测试证实了这种情况, 但时间不变,速度缓慢仍然很慢。 在我的测试中,向控制台写入一长串退格比SetCursorPosition快,直到60个字符左右。 因此,用于替换短于60个字符(或大约60个字符)的行的部分更快, 并且它不闪烁,所以我将支持 b通过 r和SetCursorPosition
最初认可。
上一篇: How can I update the current line in a C# Windows Console App?
下一篇: How to run a C# console application with the console hidden