none
TreeView加载大量树节点出现假死情况,启用Task和Dispatcher也还是这种情况,是线程代码写的不对还是其他的原因? RRS feed

  • 问题

  •  Task a = new Task(() =>
                {
                    App.Current.Dispatcher.Invoke((Action)(() =>
                    {
                        loadTagTree();//加载树节点
                    }));
                });
                a.Start();
    
    //以下是方法调用loadTagTree方法最终会调用的加载树节点的方法
    public void seelctTtest(ObservableCollection<TagTree> List)
            {
                List.Clear();//List是treeView绑定的树形数据集合
                for (int i = 0; i < 100; i++)
                    {
                            App.Current.Dispatcher.Invoke((Action)(() =>
                            {
                                List.Add(getTestTagOfMaxTop());  //getTestTagOfMaxTop:随机获取一个最上级节点的方法
                            }));
                    }
                    foreach (var ki in List)
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            App.Current.Dispatcher.Invoke((Action)(() =>
                            {
                                ki.NextTreeList.Add(getTestTag(ki));  //getTestTag:随机获取一个非最上级节点的方法
                            }));
                    
                        }
                    }
                    foreach (var ki in List)
                    {
                        foreach (var k in ki.NextTreeList)
                        {
                            for (int i = 0; i < 100; i++)
                            {
                                    App.Current.Dispatcher.Invoke((Action)(() =>
                                    {
                                        k.NextTreeList.Add(getTestTag(k));
                                    }));
                            }
                        }
                    }
            }
    
    
    
    如代码所示,先加载顶级节点,然后加载每个顶级节点的第二级,然后加载每个第二级节点的第三集节点,共加载有100*100*100个节点。出现界面假死情况后,启用Task和Dispatcher,但是没有效果,是线程代码写的不对还是其他原因?
    2018年9月7日 4:32

全部回复

  • UI虚拟化 https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/optimizing-performance-controls

    数据虚拟化 https://www.codeproject.com/Articles/34405/WPF-Data-Virtualization

    循环写得不是很好,三重循环一次都搞定了。你的问题跟Dispatcher没有关系,Dispatcher作用是后台线程需要访问界面元素时使用的。TreeView默认未启动UI虚拟化功能,这是假死的原因。另外1M个元素即使使用虚拟化也会卡顿,可以参考数据虚拟化

    2018年9月11日 14:51