私はリアルタイムのWPF/Silverlight(および間もなくWP7)視覚化コンポーネントに取り組んでおり、ゲームループスタイルでコンポーネント全体を強制的に再描画するための最良のソリューションを探しています。再描画はオンデマンドである必要がありますが、再描画呼び出しでメッセージポンプをバックアップしたくありません。コンポーネントの描画のほとんどは、非WPFプリミティブ(Bitmap Interop、Direct2Dなど)を使用して行われるため、コードはInvalidateVisualを使用せず、その結果、現在は次のようになります。
// Pseudocode, doesnt compile, just to convey the meaning
public void InvalidateElement()
{
if (CurrentlyDrawing)
return;
Dispatcher.BeginInvoke(() =>
{
CurrentlyDrawing = true;
DoDrawInternal();
CurrentlyDrawing = false;
}
}
さて、これは素晴らしいです。InvalidateElementを何度も呼び出すと、応答性が良くなります。ただし、私がやりたいのは、データを視覚化コンポーネントにできるだけ速くプッシュできるようにすることですが、コンポーネントが描画できる場合にのみ描画し、入力ストリームが完了した後はデータに追いつくために描画を続けないようにします。
いいえ、OnRenderをオーバーライドできません。WPF内で非WPF描画を使用しています;-)
基本的に私が欲しいのは、WindowsFormsの古いInvalidate()/ OnPaintのようなもの、さらにはDirectXのゲームループのようなものです。
現時点では、データを視覚化コンポーネントに高速でプッシュする外部スレッドがある場合、データのプッシュを停止すると、コンポーネントの描画が停止する前に、さらに20秒分の更新が行われるという状況になります。データが入ったらすぐに描画をやめたいです。
私が持っていたもう1つのアイデアは、視覚化コンポーネントでCompositionTarget.Renderingを処理してから、データをプッシュするためのある種の基本的なキューを実装し、Renderingイベントがこのデータをできるだけ速く消費することでした。
要約すれば
WPF視覚化コンポーネントVと、1msごとにデータをプッシュするデータソースDがある場合、Dのデータレートに関係なく、Vが30FPS(またはそれが実行できるもの)でデータを描画し、チャンクで更新することをどのように確認できますか? DirectXでゲームレンダリングループがどのように機能するのでしょうか。
データが停止すると、Vはこれまでのすべてを一度に再描画する必要があります。データが速すぎる場合、Vはそれを補うために一度に大きなチャンクを描画します。
さらに情報が必要な場合は、喜んで共有させていただきます。今、私は簡単な修正があるかどうかを判断するための概要を投稿しましたが、コード例を含むより完全なQをリクエストに応じて提供できます。
よろしくお願いします、