这就是问题所在:我有一个自定义硬件设备,我必须在 C#/WPF 中从中获取图像并将它们显示在一个窗口中,所有这些都具有 120+ FPS。
问题是没有事件表明图像已准备就绪,但我必须不断轮询设备并检查是否有任何新图像然后下载它们。
显然有几种方法可以做到这一点,但我还没有找到合适的方法。
这是我尝试过的:
一个简单的计时器(或 DispatcherTimer) - 适用于较慢的帧速率,但我无法让它超过 60 FPS。
一个单线程无限循环 - 非常快,但我必须将 DoEvents/它的 WPF 等效项放入循环中,以便重绘窗口;这会产生一些其他不需要的(奇怪)后果,例如某些控件未触发的按键事件等。
在另一个线程中进行轮询/下载并在 UI 线程中显示,如下所示:
new Thread(() => { while (StillCapturing) { if (Camera.CheckForAndDownloadImage(CameraInstance)) { this.Dispatcher.Invoke((Action)this.DisplayImage); } } }).Start();
好吧,这工作得比较好,但是会给 CPU 带来相当大的负载,如果它没有超过一个 CPU/核心,当然会完全杀死机器,这是不可接受的。另外,我这种方式存在大量线程争用。
问题很明显——有没有更好的选择,或者在这种情况下是其中一种方法吗?
更新:
我不知何故忘了提到这一点(好吧,写这个问题时忘了考虑它),但是我当然不需要显示所有帧,但是我仍然需要捕获所有帧以便保存它们到硬盘。
Update2: 我发现 DispatcherTimer 方法很慢不是因为它不能足够快地处理所有事情,而是因为 DispatcherTimer 在触发滴答事件之前等待下一次垂直同步;这在我的情况下实际上很好,因为在滴答事件中,我可以将所有待处理的图像保存到内存缓冲区(用于将图像保存到磁盘)并只显示最后一个。
至于被捕获完全“杀死”的旧计算机,WPF似乎退回到非常慢的软件渲染。我可能无能为力。
感谢所有的答案。