C#异步LCD写入

标签 c# .net wpf asynchronous concurrency

所以我正在研究一个涉及每秒更新 60 次的 LCD 屏幕的项目。它使用 BitmapFrame,我需要将这些像素复制到更新屏幕的库。目前我的帧速率约为 30-35 FPS,这太低了。所以我尝试使用多线程,但这会产生很多问题。

DisplayController 已经创建了一个标题来完成所有工作,如下所示:

public void Start()
{
    _looper = new Thread(Loop);
    _looper.IsBackground = true;
    _looper.Start();
}

private void Loop()
{
    while (_IsRunning)
    {
        renderScreen();
    }
}

它调用renderScreen方法来绘制所有元素并将像素复制到BitmapFrame。但这个过程花费的时间太长,所以我的 FPS 下降了。我尝试解决这个问题的方法是创建一个绘制、复制和写入像素的任务。但此解决方案会占用大量 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# 并发队列的内容,但这不是我需要的。使用两个线程会导致编译器说该变量由另一个线程拥有的问题。

如何同时渲染新位图并将该位图每秒 60 次写入 LCD?

最佳答案

我假设USBD480_DrawFullScreenBGRA32是实际写入LCD的内容,其余代码只是准备图像。我认为提高性能的关键是在写入上一个图像的同时准备下一个图像。

我认为最好的解决方案是使用两个线程并使用 ConcurrentQueue作为需要写入内容的缓冲区。一个线程准备图像和 puts them into the ConcurrentQueue ,另一个线程 pulls them off the queue并将它们写入 LCD。这样您就不需要每次调用 Task.Run 的开销。

限制写入队列的帧数也可能是明智的,这样它就不会超前太多并占用不必要的内存。

关于C#异步LCD写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58402150/

相关文章:

c# - 采用构造函数的方法参数

c# - 使用 EF6 和 SQL Server 2012 时是否有替代方法来引用表?

.net - 用于解析命令行参数的正则表达式失败

wpf - 使用 WPF 工具包 DatePicker 作为 ObjectDataProvider 的参数,用作 itemssource

c# - 剪贴板中的 Null unicode 无法粘贴

c# - XmlSchemaException C#

c# - 将 .xml 文件读入 XmlDocument

c# - 如何自定义 MSI 安装程序中的错误屏幕?

.net - T4 用于在 LLBLGen Pro 实体上生成 POCO?

wpf - 如何将 View 拆分为 m-v-vm 中的模块