简体   繁体   English

在WPF中快速删除(并添加)许多项目到Canvas

[英]Rapidly removing (and adding) many items to a Canvas in WPF

At a certain point in my WPF application, the UI thread will lock up for ~0 till ~500 ms (depending on the amount) once I remove and/or add items to a Canvas. 在我的WPF应用程序中的某个点上,一旦我移除和/或添加项目到Canvas,UI线程将锁定〜0到~500 ms(取决于数量)。 Several performance tests pointed to Canvas.Children.Remove for the main cause, and .Add as well (.Remove is much more severe). 几个性能测试指出Canvas.Children.Remove是主要原因,而.Add也是(.Remove更严重)。 I remove about 500 items at the same time, and add about 500 items at the same time as well. 我同时删除了大约500个项目,同时添加了大约500个项目。 This about 10 times per second causes issues. 这大约每秒10次会导致问题。

In the end, I've written a simple benchmarking application, code below. 最后,我编写了一个简单的基准测试应用程序,代码如下。

    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));
        };
    }

This gives the following result (around this, every time I run it): 这给出了以下结果(每次我运行它时):

Add: 174, Remove: 156.

Keep in mind only 750 items get removed, while 7500 get added. 请记住,只有750项被删除,而7500项被添加。

The process is a bit heavy, but I don't want the UI ( ScrollViewer mainly) to lock up while it's doing this. 这个过程有点沉重,但我不希望UI(主要是ScrollViewer )在执行此操作时锁定。 Another problem I face is that I can't "just move" this to another Thread , since I can't control the UI from that specific Thread . 我面临的另一个问题是我无法“将其移动”到另一个Thread ,因为我无法从该特定Thread控制UI。

How to improve this process? 如何改进这个过程? Or is there a way to dynamically add/remove items "over time" so it does not hang up? 或者有一种方法可以“随着时间的推移”动态添加/删除项目,因此它不会挂断?

Thanks, 谢谢,

~Tgys 〜Tgys

What if you split this into new thread and dispatch the work into UI thread with every 20ms or so? 如果将其拆分为新线程并将工作分配到UI线程每20ms左右怎么办? This way you wont completely lock the UI up. 这样你就不会完全锁定UI了。 So the user could do other things in meanwhile. 因此,用户可以同时做其他事情。

Other things I know: Is there a AddRange method? 我知道的其他事情:是否有AddRange方法? Perhaps you could add all items at once. 也许你可以一次添加所有项目。 This way only one layout update would theoretically happen cutting the time into zero. 这样,理论上只会发生一次布局更新,将时间缩短为零。

Same for Remove. 删除相同。 See Canvas.Children.RemoveRange(a); Canvas.Children.RemoveRange(a);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM