3

アプリケーションでパフォーマンスの問題が発生しています。基本的にボタンをクリックすると、リストにデータバインドされたデータが入力され(これは大量のデータのために仮想化されます)、次に別のボタンをクリックして、関連するリストビューに行を追加します。UIで実際に何が起こっているかを説明するだけでよいと思うので、漠然としています。

これが私が知っていることです:

  • Win 7 Proを実行している頑丈な開発用コンピューターでも、適切な仕様のXP SP3マシンでも、この問題は発生しません。4GBのRAMとCorei5CPU(XPデスクトップよりもはるかに強力)を備えたWin 7エンタープライズを実行している特定のブランドのラップトップ(Lenovo ThinkPad)でのみ表示されます。
  • 前述の調査結果のため、これがコードの問題であるとは考えていません。
  • MicrosoftのPerfViewツールを使用してプロファイルを作成し、 UIElement.Measure (コードによって直接呼び出されることはありません)への非常に多くの呼び出しであると想定されることに気付きました。これは、他のマシンでプロファイルを作成したときに表示されません。
  • ラップトップの解像度は1360x780なので、解像度が低いために、データバインディングが原因で、GPUがコントロールを不必要にレンダリングしているのではないかと思いました(これにより、Measure()の呼び出しが多数発生する可能性があります)。ラップトップのディスプレイを24インチモニターに拡張しましたが、改善は見られませんでした。

今のところ、問題はGPUにあると思います。ドライバーを更新しましたが、改善はありません。

  1. コードの問題ではないと思いますが、「SuspendLayout()」に相当するWPFはありますか?
  2. GPUのパフォーマンスをプロファイリングして、特定のプロセス中に打撃を受けているかどうかを確認する方法はありますか?
  3. (ファーショット)コンピュータ固有のように見える同様のパフォーマンスの問題と、それらを追跡する方法についての提案があった人はいますか?

これが漠然とした質問である場合は申し訳ありません。SOの使用要件に準拠するようにしました。さらに情報が必要な場合はお知らせください。

補遺と同じように、プログラムはWPF、C#4.0を使用していますが、問題はTelerikコントロールにあるようです(ただし、他の場所で問題なく使用しているため、疑わしいとは思いません)。

4

2 に答える 2

2

既知のMicrosoftの問題が原因であることが判明しました。説明しようと思いますが、説明しません。主に私ができないからです。

修正について話している記事(2010年8月3日のViðarによる投稿を参照):

Microsoft Hotfixサイト:http ://support.microsoft.com/kb/2484841/en-us

修正:http ://archive.msdn.microsoft.com/KB2484841/Release/ProjectReleases.aspx?ReleaseId = 5583

于 2013-02-25T19:24:27.607 に答える
1

1.回答

MeasureOverrideWPFから発信される横行する呼び出しを防ぐにはContextLayoutManager

protected override void OnChildDesiredSizeChanged(UIElement el)
{
    /* base.OnChildDesiredSizeChanged(el); */       // avoid rampant remeasuring
}

2.関連する引用

UIElement.OnChildDesiredSizeChanged(UIElement) Method
  ...
メソッドには、それ自体を呼び出すというデフォルトの実装があり
ます。典型的な実装は次のようになります:独自の要素がサポートする最適化を実行し、通常、コードブランチのa̲t̲l̲e̲a̲s̲t̲o̲n̲e̲からbaseを呼び出します。OnChildDesiredSizeChanged(UIElement)InvalidateMeasure()OnChildDesiredSizeChanged(UIElement)

...その子のいずれかによって作成された単一の親レイアウトパスの場合、親のは、その子のそれぞれMeasureOverrideに対して1回、追加で(おそらくは無関係に)呼び出されるという意味(および事実)です。サイズも変更されました。

3.ディスカッション

複数の子が「同時に」サイズを変更する場合、親は通常、これらの呼び出しの最初の呼び出し中に、すべての子の中で新しい全体的なレイアウトを完全に検出して説明します。これはWPFの標準的な方法であり、特定のトリガーとなる子の兆候を意図的に除外することで推奨されます。最も一般的なケースではそのような子がないという事実に加えて(詳細については上記のリンクを参照)、あらゆる種類の「部分的なレイアウト」を試みるためのコードが面倒になります。しかし、ほとんどの場合、とにかく利用可能な最新の測定値をすべて最初に取得せずに、レイアウト計算を続行したいのはなぜですか?MeasureOverride(…)

したがってMeasureOverride、たまたま「最初」の子によってトリガーされた1回の呼び出しの後(問題ではない)、親のレイアウトは、最新の子サイズ情報のすべてに関して実際に最終的なものになるはずです。OnChildDesiredSizeChangedただし、これは、キューに入れられた通知(サイズも変更された他の子)がなくなったことを意味するものではありません。これらの呼び出しはまだ親で保留中であり、仮想ベース呼び出しが明示的に放棄されない限り(箇条書き#1に示すように)、それぞれが1つの追加の外部MeasureOverride呼び出しを生成します。

4.警告

ここに示すコードは子供が開始するメジャーの無効化を無効にします。これは、親がそのような変更を故意に禁止するか、本質的にすでにそれらを認識している場合に適しています。これは珍しいことではありません。たとえば、子のサイズを常に完全に決定して適用する親、またはより一般的にはDesiredSize、独自のメジャーパス中に子からの値のみを採用する親が含まれます。重要なのは、親の測定がそれ自身の親によってのみ十分に保証されるということです。

親が子が開始したメジャー通知の一部をキャンセルし、他の通知を保持/許可する場合は、当然、追加の特定の状況によって異なります。それはもっとあいまいに見えるので、ここでは取り上げません。

于 2021-04-12T21:56:17.460 に答える