ここに問題があります: 私はカスタム ハードウェア デバイスを持っており、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 がティック イベントを発生させる前に次の垂直同期を待機するためであることがわかりました。tick イベントでは、保留中のすべての画像をメモリ バッファー (画像をディスクに保存するために使用) に保存し、最後の画像だけを表示できるため、これは実際に私の場合は良いことです。
キャプチャによって完全に「殺されている」古いコンピューターに関しては、WPF は非常に遅いソフトウェア レンダリングにフォールバックするようです。私にできることはきっと何もない。
すべての答えをありがとう。