如何在同一行上打印两种不同颜色的文本(控制台)?
How can I print text in two different colours (console) on the same line?
我正在尝试在同一行中写入文本,并在行的中途改变颜色。目前我把它分成两个独立的部分,每次都改变颜色,只是使用 Console.Write
而不是 WriteLine
.
这对于过程操作来说很好,但是当我 运行 异步任务时,我遇到了很多同步问题。
是否可以在不使用外部库的情况下更改 WriteLine
中的文本颜色?
使用 ConcurrentQueue:
试试这个愚蠢的例子
public class Message
{
public List<MessagePart> parts = new List<MessagePart>();
public void Render()
{
parts.ForEach(p => p.Render());
}
public class MessagePart
{
public string text;
public ConsoleColor color;
public MessagePart(string text, ConsoleColor color)
{
this.text = text;
this.color = color;
}
public void Render()
{
Console.ForegroundColor = color;
Console.Write(text);
}
}
}
class Program
{
static bool pause = false;
static bool quit = false;
static ConcurrentQueue<Message> messages = new ConcurrentQueue<Message>();
static void Main(string[] args)
{
Console.WriteLine("Press Space to Pause/UnPause.");
Console.WriteLine("Press Enter to Quit when you are done.");
Console.WriteLine("Press Enter to Start...");
Console.ReadLine();
Task.Run(() => RenderLoop());
Task.Run(() => YellowAndBlue());
Task.Run(() => RedAndBlue());
while (!quit)
{
while (!Console.KeyAvailable)
{
System.Threading.Thread.Sleep(50);
}
switch(Console.ReadKey(false).Key)
{
case ConsoleKey.Enter:
quit = true;
break;
case ConsoleKey.Spacebar:
pause = !pause;
break;
}
}
}
static void YellowAndBlue()
{
Message msg = new Message();
msg.parts.Add(new Message.MessagePart("Yellow", ConsoleColor.Yellow));
msg.parts.Add(new Message.MessagePart(" and ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Blue", ConsoleColor.Blue));
msg.parts.Add(new Message.MessagePart(" make ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Green\r\n", ConsoleColor.Green));
while (!quit)
{
System.Threading.Thread.Sleep(25);
messages.Enqueue(msg);
while (pause)
{
System.Threading.Thread.Sleep(50);
}
}
}
static void RedAndBlue()
{
Message msg = new Message();
msg.parts.Add(new Message.MessagePart("Red", ConsoleColor.Red));
msg.parts.Add(new Message.MessagePart(" and ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Blue", ConsoleColor.Blue));
msg.parts.Add(new Message.MessagePart(" make ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Magenta\r\n", ConsoleColor.Magenta));
while (!quit)
{
System.Threading.Thread.Sleep(25);
messages.Enqueue(msg);
while (pause)
{
System.Threading.Thread.Sleep(50);
}
}
}
static void RenderLoop()
{
Message message;
while (!quit)
{
while (!messages.IsEmpty && !quit)
{
if (messages.TryDequeue(out message))
{
message.Render();
}
while (pause)
{
System.Threading.Thread.Sleep(50);
}
}
if (!quit)
{
messages.Enqueue(new Message() { parts = { new Message.MessagePart("Queue Emptied!\r\n", ConsoleColor.White) } });
System.Threading.Thread.Sleep(100);
}
}
}
}
输出(暂停):
我正在尝试在同一行中写入文本,并在行的中途改变颜色。目前我把它分成两个独立的部分,每次都改变颜色,只是使用 Console.Write
而不是 WriteLine
.
这对于过程操作来说很好,但是当我 运行 异步任务时,我遇到了很多同步问题。
是否可以在不使用外部库的情况下更改 WriteLine
中的文本颜色?
使用 ConcurrentQueue:
试试这个愚蠢的例子public class Message
{
public List<MessagePart> parts = new List<MessagePart>();
public void Render()
{
parts.ForEach(p => p.Render());
}
public class MessagePart
{
public string text;
public ConsoleColor color;
public MessagePart(string text, ConsoleColor color)
{
this.text = text;
this.color = color;
}
public void Render()
{
Console.ForegroundColor = color;
Console.Write(text);
}
}
}
class Program
{
static bool pause = false;
static bool quit = false;
static ConcurrentQueue<Message> messages = new ConcurrentQueue<Message>();
static void Main(string[] args)
{
Console.WriteLine("Press Space to Pause/UnPause.");
Console.WriteLine("Press Enter to Quit when you are done.");
Console.WriteLine("Press Enter to Start...");
Console.ReadLine();
Task.Run(() => RenderLoop());
Task.Run(() => YellowAndBlue());
Task.Run(() => RedAndBlue());
while (!quit)
{
while (!Console.KeyAvailable)
{
System.Threading.Thread.Sleep(50);
}
switch(Console.ReadKey(false).Key)
{
case ConsoleKey.Enter:
quit = true;
break;
case ConsoleKey.Spacebar:
pause = !pause;
break;
}
}
}
static void YellowAndBlue()
{
Message msg = new Message();
msg.parts.Add(new Message.MessagePart("Yellow", ConsoleColor.Yellow));
msg.parts.Add(new Message.MessagePart(" and ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Blue", ConsoleColor.Blue));
msg.parts.Add(new Message.MessagePart(" make ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Green\r\n", ConsoleColor.Green));
while (!quit)
{
System.Threading.Thread.Sleep(25);
messages.Enqueue(msg);
while (pause)
{
System.Threading.Thread.Sleep(50);
}
}
}
static void RedAndBlue()
{
Message msg = new Message();
msg.parts.Add(new Message.MessagePart("Red", ConsoleColor.Red));
msg.parts.Add(new Message.MessagePart(" and ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Blue", ConsoleColor.Blue));
msg.parts.Add(new Message.MessagePart(" make ", ConsoleColor.White));
msg.parts.Add(new Message.MessagePart("Magenta\r\n", ConsoleColor.Magenta));
while (!quit)
{
System.Threading.Thread.Sleep(25);
messages.Enqueue(msg);
while (pause)
{
System.Threading.Thread.Sleep(50);
}
}
}
static void RenderLoop()
{
Message message;
while (!quit)
{
while (!messages.IsEmpty && !quit)
{
if (messages.TryDequeue(out message))
{
message.Render();
}
while (pause)
{
System.Threading.Thread.Sleep(50);
}
}
if (!quit)
{
messages.Enqueue(new Message() { parts = { new Message.MessagePart("Queue Emptied!\r\n", ConsoleColor.White) } });
System.Threading.Thread.Sleep(100);
}
}
}
}
输出(暂停):