c# - C#做更多的线程加速写入控制台而不相互干扰
问题描述
我目前正在开发一个简单的命令行程序,它有一个像素类,并将其显示到控制台是最慢的部分。我可以使用多个线程来加快写入控制台的速度吗?
你的 Vector2D 类只保存 ax 和 y 位置。如果 x 和 y 与比较值相同,则 equals 函数返回
像素渲染器功能看起来有点像
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
操作都由并发锁控制,这将导致线程相互限制。
如果您需要加快控制台渲染速度,我建议您实现一个缓冲区(例如 achar[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()
.
推荐阅读
- c# - 选择重复对象的所有数据
- python - 电子邮件 Python 脚本输出
- javascript - websockify ws.send 没有向 telnet 服务器发送字符串
- python - Nelder-Mead 优化中的终止容差
- ms-access - MS Access DateDiff 模糊日期(日月顺序)返回错误结果
- discord - 尝试发布 webhook 时,我不断收到空消息错误
- load - 如何使用 Soap UI 针对特定时间和特定线程数进行负载测试
- php - 自迁移到 Symfony 3 以来,foreach on null 会引发错误
- python - Python:“NoneType”类型的对象没有 len()
- javafx - 将 JavaFx 标签绑定到根据三个节点属性更改的函数输出