3

WPFアプリケーションを改善するための最良の解決策を知りたいです。

WPFでは、UIを作成したスレッドですべてのUI作業を実行する必要があることを知っています。これは私にとって大きな問題です。UIが非常に大きく、ウィンドウが1つしかないため、ウィンドウごとに1つのスレッドを分割できないためです。

パンとズームを行うときは、毎回すべてを更新する必要があります。すべてが完了するまで、CPUの1つが100%の使用率に達します。

だから私は私のアプリケーションに何があるかを説明しようとします:

  • 1ウィンドウ(画面サイズ)
  • 仮想パネル、12000ピクセルX 12000ピクセル(パンとズームを行う場所)
  • 約2000のコントロール(ボタン、スイッチ、およびその他の複雑なコントロール)
  • コントロールの後ろに、背景用の大きなビットマップがありますが、背景を100個の小さなビットマップのように分割してスタックします(12kピクセル×12kピクセルの1ビットマップがアプリをクラッシュさせるため)
  • (ビットマップをフィードする)離れたコンピューターに接続され、50ミリ秒ごとにコンテンツを更新する10個の仮想ディスプレイ
  • .NET 4.0、マルチタッチアプリケーション

つまり、パンとズームを実行できるアプリケーション(10個のディスプレイなし)では、コントロールの量に多くのラグがあり、ディスプレイを配置すると、ラグが2倍になります...

私のアプリケーションは約1.5GBの仮想メモリを使用します。

できる限りディスパッチャを使用してスレッドを作成するように検索しましたが、必要なものが見つかりません...どこでも1つのスレッド/ウィンドウについて話していました...しかし、ウィンドウが1つしかないため、どうすればよいかわかりません。

  • 小さいウィンドウに分割できません。
  • コントロールの量や更新時間を減らすことはできません。
  • テクノロジーを変更できません(WPF)

だからここに本当の質問があります:レンダリング時間を助けるためにどこで新しいスレッドを作成できますか?ジョブを別のCPUに分割するには...

私は彼らがこれについて話している別のウェブサイトを見つけました...しかし私の質問に答えていません:

複数のUIスレッドを使用したWPFアプリケーションの実行

MSDN

WPFディスパッチャーの操作

4

3 に答える 3

2

それで私はそれについて少し調べました。1つのアプリケーションが別のスレッドで別のウィンドウまたはページを作成できます:ここから取得したコードの一部

  private void OnCreateNewWindow(
  object sender,
  RoutedEventArgs e)
  {
    Thread thread = new Thread(() =>
    {
      Window1 w = new Window1();
      w.Show();

      w.Closed += (sender2, e2) =>
      w.Dispatcher.InvokeShutdown();

      System.Windows.Threading.Dispatcher.Run();
    });

   thread.SetApartmentState(ApartmentState.STA);
   thread.Start();
  }

それは良いニュースでした。しかし、あなたの場合、ウィンドウが1つあるので、実際には当てはまりません。これを試してみましたが、実際には機能しません。

     private void OnCreateNewWindow(object sender, RoutedEventArgs e)
     {
       SynchronizationContext syncContext = SynchronizationContext.Current;
       var btn = sender as Button;
       var st = btn.Parent as StackPanel;

       Thread thread = new Thread(() =>
         {
            Button button = new Button();
            syncContext.Post(delegate { st.Children.Add(button) ;}, null); //Exception here
         });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
     }

別のスレッドで別のコントロールを作成しようとしましたが、これは機能しますが、stackPanelに追加しようとすると、失敗します。 InvalidOperationException

私はそれがあなたの質問に直接答えないことを知っています、しかし私は少なくともあなたは同じ中のすべてのコントロールがWindow同じスレッドに属していなければならないことを知っています。

于 2012-07-09T12:51:35.947 に答える
1

何よりも仮想化を使用する必要があるようです。ユーザーはいつでも仮想ワークスペースのごく一部しか見ることができないため、その部分のみを更新する必要があります。

それ以外に、プロファイリングしましたか?CPUを正確に固定しているのは何ですか?

于 2012-07-09T12:02:07.170 に答える
0

ズームするときに、これらのコントロールを「偽造」して背景にペイントします。コントロールのように見える小さな画像を描くこともできます。小さい(拡大縮小された)背景を使用すると、ズームを高速化できます。次に、準備ができたら、2kコントロールを同時に使用する必要があることをイメージできないため、表示/操作できるコントロールのみを再描画または追加します。すべてのコントロールのx、yを計算し、それらがビュー長方形に存在するかどうかを確認して描画する方が、すべてを描画するよりもはるかに高速です。

スペクタクルグラフィックのほとんどは、この種のトリックで行われます。

于 2012-09-24T20:08:16.417 に答える