3

WPFアプリケーションの特定の時点で、Canvasにアイテムを削除または追加すると、UIスレッドは(量に応じて)約0から約500ミリ秒の間ロックされます。いくつかのパフォーマンステストでは、Canvas.Children.Removeが主な原因であり、.Addも同様に指摘されています(.Removeの方がはるかに深刻です)。同時に約500個のアイテムを削除し、同時に約500個のアイテムを追加します。これは1秒間に約10回発生し、問題が発生します。

最後に、以下のコードで簡単なベンチマークアプリケーションを作成しました。

    public MainWindow() {
        InitializeComponent();
        this.Loaded += (object sender, RoutedEventArgs e) => {
            List<Image> a = new List<Image>();
            Stopwatch s = new Stopwatch();
            s.Start();
            for (int i = 0; i < 7500; i++) {
                Image img = new Image();
                Canvas.SetLeft(img, i * 10);
                C.Children.Add(img);
                if (i % 10 == 1)
                    a.Add(img);
            }
            s.Stop();
            long add = s.ElapsedMilliseconds;
            s.Reset();
            s.Start();
            foreach (Image img in a) {
                C.Children.Remove(img);
            }
            s.Stop();
            MessageBox.Show(String.Format("Add: {0}, Remove: {1}.", add, s.ElapsedMilliseconds));
        };
    }

これにより、次の結果が得られます(これを実行するたびに、このあたりで):

Add: 174, Remove: 156.

削除されるのは750アイテムのみで、7500アイテムが追加されることに注意してください。

プロセスは少し重いですが、これを実行している間、UI(ScrollViewer主に)がロックされないようにします。Thread私が直面しているもう1つの問題は、特定のからUIを制御できないため、これを別の場所に「移動」できないことThreadです。

このプロセスを改善する方法は?または、「時間の経過とともに」アイテムを動的に追加/削除して、ハングアップしないようにする方法はありますか?

ありがとう、

〜Tgys

4

1 に答える 1

2

これを新しいスレッドに分割し、20ミリ秒ごとに作業をUIスレッドにディスパッチするとどうなりますか?このようにして、UIを完全にロックすることはありません。そのため、ユーザーはその間に他のことを行うことができます。

私が知っている他のこと:AddRangeメソッドはありますか?おそらく、すべてのアイテムを一度に追加できます。このようにすると、理論的には1つのレイアウト更新のみが発生し、時間がゼロになります。

削除についても同じです。見るCanvas.Children.RemoveRange(a);

于 2012-09-20T14:12:13.203 に答える