none
WPF 异步更新界面如何保证排序正确 RRS feed

  • 问题

  • 现在有个需求,需要将大量图片按图片的创建时间从大到小依次展示在ListBox中,目前如果使用界面线程的同步插入(Dispatcher.Invoke),可以保证图片排序的正确,但界面会有卡顿,如果使用异步插入(Dispatcher.BeginInvoke),界面流畅性会好很多,但图片插入时由于是异步,当插入的方法执行时,Insert的索引位置是错误的,难道鱼和熊掌当真不可兼得吗?
    2019年5月9日 6:13

答案

  • Hi    bp_l,

    >>itemSource是ObservableCollection<T>类型,我试过,就算itemSource不绑定ListBox的ItemSource,无任何地方引用,也会引起界面的卡顿。目前找不到很好的解决方案,也许只能从业务方面进行妥协了

    我这边试了下,没有卡顿。

                int indexro = listss.Count;
                for (int i =0; i <10000; i++)
                {
                    Dispatcher.Invoke(new Action(() => {
    
                        listss.Insert(indexro, new testdem() { name = indexro.ToString(), address = "HHikh4", Showcheckpoint = "check04" });
                        indexro++;
                    }));
                }

    也许你可以给我们一个可以运行并还原你现象的例子。


    Best Regards

    Yong Lu

     

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2019年5月10日 1:40
    版主

全部回复

  • 个人拙见

    请谨慎!!

    异步的特性如此

    Listbox自己有虚拟化,讲道理不应该卡啊

    我自己写了个listbox加载图片的,每个都是实例不是引用的,加载1W个 基本也都是秒开啊

    你是如何处理加载?

    1直接将图片转换成stream之后加载到listbox

    2先将图片地址加载到集合中后将集合设置为listbox的数据源

    3将图片stream加载到集合中后将集合设置为listbox的数据源

    我不太清楚你具体实现的过程,最好你能将你的代码整合贴上来,不过我有个思路

    使用第三个方法,只不过不先加载流,在设置为listbox的数据源过后异步加载图片流到集合中,这样子就可以确定索引了。还有前提是首先确定好加载图片的顺序。





    • 已编辑 ARM830 2019年5月9日 8:46
    2019年5月9日 8:29
  • 谢谢回复,我的情况不是加载图片导致的卡顿,是频繁调用界面线程引起的卡顿,打个比方:循环调用10000次 

    Dispatcher.invoke(new Action(() =>{

    itemSource.insert(index,imageItem)

    }))

    itemSource是ObservableCollection<T>类型,我试过,就算itemSource不绑定ListBox的ItemSource,无任何地方引用,也会引起界面的卡顿。目前找不到很好的解决方案,也许只能从业务方面进行妥协了

    2019年5月9日 12:07
  • 你最好将你的代码贴上来 或者稍微整合一下

    我这面单线程使用Dispatcher.BeginInvoke1W次是不会卡顿的

    如果是1W个线程每个线程操作一次 卡顿时间不过10S

    我这面顺序也是可以正确

        List<Test> tests = new List<Test>();
        public   MainWindow()
            {
                InitializeComponent();
        
                
                lb.ItemsSource = tests;
                for (int i=0; i < 10000; i++)
                    tests.Add(new Test());
    
    
            }
            void Start()
            {
    
    
                int i = 0;
    
                for (; i < 10000; i++)
                {
                          this.Dispatcher.Invoke(() =>
                          {
                              Set(i);
                          });
                }
            }
            void Set(object i)
            {
                
                action = Add;
    
                lb.Dispatcher.BeginInvoke(action, DispatcherPriority.Normal  , i);
            }
            public Action<int> action;
    
            void Add(int i)
            {
                lb.Dispatcher.Invoke(() => {
                    tests[i]=(new Test()
                    {
                        Nub = i.ToString(),
                        Img = new BitmapImage(new Uri(@"C:\Users\wppcn\source\repos\WPF QQ MVVM\异步图片\t.jpg"))
                    });
                });
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
    
                Start();
            }

    • 已编辑 ARM830 2019年5月10日 5:08
    2019年5月9日 18:21
  • Hi    bp_l,

    >>itemSource是ObservableCollection<T>类型,我试过,就算itemSource不绑定ListBox的ItemSource,无任何地方引用,也会引起界面的卡顿。目前找不到很好的解决方案,也许只能从业务方面进行妥协了

    我这边试了下,没有卡顿。

                int indexro = listss.Count;
                for (int i =0; i <10000; i++)
                {
                    Dispatcher.Invoke(new Action(() => {
    
                        listss.Insert(indexro, new testdem() { name = indexro.ToString(), address = "HHikh4", Showcheckpoint = "check04" });
                        indexro++;
                    }));
                }

    也许你可以给我们一个可以运行并还原你现象的例子。


    Best Regards

    Yong Lu

     

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2019年5月10日 1:40
    版主