【发布时间】:2019-10-15 20:23:08
【问题描述】:
所以我正在做一个涉及每秒可更新 60 次的 LCD 屏幕的项目。它使用BitmapFrame,我需要将这些像素复制到更新屏幕的库中。目前我得到大约 30-35 FPS,这太低了。所以我尝试使用多线程,但这会产生很多问题。
DisplayController 已经创建了一个 thead 来完成所有工作,如下所示:
public void Start()
{
_looper = new Thread(Loop);
_looper.IsBackground = true;
_looper.Start();
}
private void Loop()
{
while (_IsRunning)
{
renderScreen();
}
}
调用renderScreen 方法绘制所有元素并将像素复制到BitmapFrame。但是这个过程需要太长时间,所以我的 FPS 下降了。我试图解决这个问题是通过创建一个Task 来绘制、复制和写入像素。但是这种解决方案会占用大量 CPU 并导致屏幕出现故障。
public void renderScreen()
{
Task.Run(() =>
{
Monitor.Enter(_object);
// Push screen to LCD
BitmapFrame bf = BitmapFrame.Create(screen);
RenderOptions.SetBitmapScalingMode(bf, BitmapScalingMode.LowQuality);
bf.CopyPixels(new Int32Rect(0, 0, width, height), pixels, width * 4, 0);
DisplayWrapper.USBD480_DrawFullScreenBGRA32(ref disp, pixels);
Monitor.Exit(_object);
});
}
我已经阅读了很多有关 C# 并发队列的信息,但这不是我需要的。并且使用两个线程会导致编译器说该变量由另一个线程拥有的问题。
如何同时渲染一个新位图并将该位图每秒写入 LCD 60 次?
【问题讨论】:
-
你的循环方法是一个无限循环,它创建并启动一个任务而不等待它完成。所以它会像每秒 1000 个任务或线程一样开始。当然,这会减慢一切,即使所有这些都在您的监视器锁定处等待,因为不断创建新任务/线程。删除 Task.Run 和 Monitor 锁。
-
@ckuri 那是我以前的版本。这导致应用程序太慢,大约 30 FPS。这就是我尝试使用 Task.Run 的原因。但是你说得对的无限循环创建部分是有道理的。
标签: c# .net wpf asynchronous concurrency