C#做更多的线程来加速写入控制台而不会相互干扰

C# Do more threads speed up writing to console without interfering with one another

我目前正在开发一个简单的命令行程序,它有一个像素 class 并将其显示到控制台是最慢的部分。我可以使用多线程来加快写入控制台的速度吗?

你的 Vector2D class 只持有一个 x 和 y 位置。 equals 函数 returns 如果它的 x 和 y 与比较值相同

pixel Renderer函数有点像

public Vector2D location { get; private set; }
public char pixel { get; private }
public ConsoleColor FG { get; private }
public ConsoleColor BG { get; private }
public int layer { get; private }
public int ID { get; private set; }


public void renderer()
        {
            foreach (Pixel pixel in GlobalPixels)
            {
                if((this.ID != pixel.ID) && (this.location == pixel.location))
                {
                    if (this.layer < pixel.layer) return;
                }
            }

            Console.SetCursorPosition(location.x, location.y);
            Console.ForegroundColor = FG;
            Console.BackgroundColor = BG;
            Console.Write(pixel);
        }

这会导致像素被放置在错误的点或颜色中吗?

如果不是,最好的方法是什么?

多线程不太可能导致大幅增加,因为 Console 操作全部由并发锁控制,这将导致线程相互节流。

如果您需要加速控制台渲染,我建议实施一个缓冲区(例如 char[80,25] 或类似的东西)并在那里写入您的像素。当你写完像素后,将整个缓冲区一次性复制到控制台,顺序是从上到下,从左到右。控制台在按顺序写行时要快得多,而当你必须重复使用 SetCursorPosition 时会更慢。

这是一个让您入门的简单示例:

public class BufferedConsole
{
    private class Cell
    {
        public char Pixel;
        public ConsoleColor ForegroundColor;
        public ConsoleColor BackgroundColor;
    }

    static private Cell[,] _buffer = new Cell[80, 25];

    static BufferedConsole()
    {
        Clear();
    }

    static void Clear()
    {
        for (int row = 0; row < 25; row++)
        {
            for (int col = 0; col < 80; col++)
            {
                _buffer[col, row] = new Cell
                {
                    ForegroundColor = ConsoleColor.Black,
                    BackgroundColor = ConsoleColor.Black,
                    Pixel = '?'
                };

            }
        }
        Refresh();
    }

    public static void Plot(int x, int y, char pixel, ConsoleColor foreColor, ConsoleColor backColor)
    {
        var cell = _buffer[x, y];
        cell.Pixel = pixel;
        cell.ForegroundColor = foreColor;
        cell.BackgroundColor = backColor;
    }

    public static void Refresh()
    {
        Console.SetCursorPosition(0, 0);
        ConsoleColor lastForeColor = ConsoleColor.White;
        ConsoleColor lastBackColor = ConsoleColor.Black;

        Console.CursorVisible = false;

        for (var row = 0; row < 25; row++)
        {
            for (var col = 0; col < 80; col++)
            {
                var cell = _buffer[col, row];
                if (lastForeColor != cell.ForegroundColor)
                {
                    Console.ForegroundColor = cell.ForegroundColor;
                    lastForeColor = cell.ForegroundColor;
                }

                if (lastBackColor != cell.BackgroundColor)
                {
                    Console.BackgroundColor = cell.BackgroundColor;
                    lastBackColor = cell.BackgroundColor;
                }

                Console.Write(cell.Pixel);
            }
            Console.WriteLine();
        }
        Console.CursorVisible = true;
    }

}

现在只需替换​​这个:

Console.SetCursorPosition(location.x, location.y);
Console.ForegroundColor = FG;
Console.BackgroundColor = BG;
Console.Write(pixel);

有了这个:

BufferedConsole.Plot(location.x, location.y, pixel, FG, BG);

...完成后,请致电 Refresh()