如何在同一行上打印两种不同颜色的文本(控制台)?

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);
            }                
        }
    }

}

输出(暂停):