【问题标题】:C# background thread causes lag in UIC#后台线程导致UI滞后
【发布时间】:2010-03-03 12:25:40
【问题描述】:

我正在开发一个实时成像系统。

UI 线程:通过计时器以 14 fps 的速度从相机中抓取图像并进行一些处理/显示。每 2 秒,通过处理选择 3 个图像(每个在磁盘上大约 1mb)写入磁盘。这些被放入共享队列中。

第二个线程:将图像出列并写入磁盘。已被赋予“最低”优先级。

当第二个线程执行写入时,它会从 UI 线程中占用大量性能,并导致捕获速度降至 14 fps 以下。不可接受。

我可以在这里做什么?我不介意写入是否需要更长的时间并排队,有足够的 RAM 和定期暂停以允许写入赶上。关键因素是 UI 线程有足够的汁液以 14 fps 的速度工作。

【问题讨论】:

  • 您是否从后台线程调用任何 UI 更新?它真的不应该影响你的 UI。
  • 等等,你为什么要在 UI 线程上从相机中抓取图像?
  • 没有人拥有单核 CPU。您正在执行某种锁定,这会减慢捕获图像的线程。

标签: c# multithreading real-time


【解决方案1】:

要获得认真的答案,您应该使用某种分析器工具。如果您搜索 stackoverflow 或 google,您会发现很多。大多数情况下,您必须为它们付费,但幸运的是,还有一些试用版可供您测试以发现问题。

但我没有任何分析器的猜测是,磁盘上的 I/O 操作会导致您的性能问题。所以也许你可以反对它,如果你尝试使用SparseFile和/或MemoryMappedFiles(我知道它是.Net 4,但因为它只是Win32 Api的包装器,你可以提取类从那里开始并在 .Net 2) 中使用它。

【讨论】:

  • 谢谢,只是为了澄清一下:应用程序的其余部分不会接触硬盘。它不等待任何读取或写入。为什么在另一个线程中写入会影响捕获/处理?它是一个双核 CPU,一个核心已被处理饱和,另一个则免费;我希望能写出来。
  • 我也没有很好的解释,但是访问硬盘总是会减慢整个系统的速度,因为它似乎总是某种瓶颈。
【解决方案2】:

实时、windows 和 c# 不能很好地结合在一起。如果帧速率降至 14fps 以下是“不可接受的”,您可以寻找一些 Windows 实时扩展,例如 RTXINtime

您也可以尝试将文件以较小的块写入磁盘,在写入操作之间添加短 Thread.Sleeps() 以允许更多任务切换并确保在每次写入后刷新文件流。

【讨论】:

    【解决方案3】:

    也许您应该在对其执行操作后将文件保存到不同的位置。文件可能在处理时被锁定,UI 线程等待它空闲。

    【讨论】:

      【解决方案4】:

      正如其他人所说:硬实时在这里不起作用。

      尝试找出设备是否共享资源(错误示例:磁盘和相机都在同一 USB 总线上)。使用分析器检查是 CPU 限制了捕获还是 IO。也许这只是您的代码的错误(泄漏资源,浪费周期)。没有人知道,但你可以(并且应该)检查一下。

      可能的“解决方案”,取决于您的发现:

      使用队列(例如 msmq)并且只是堆积图像并且永远不会从那里读取(即使线程优先级降低),直到您达到“暂停”。不过,这确实需要“充足的 RAM”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-03
        • 2018-06-12
        • 2019-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多