异步添加到 ObservableCollection(或替代方案) [英] Asynchronously adding to ObservableCollection (or an alternative)

查看:16
本文介绍了异步添加到 ObservableCollection(或替代方案)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我所拥有的- ItemsSource 设置为 ObservableCollection 的 ListBox- 其中 T 是表示文件的自定义类,仅包含 2 个 DependencyProperties:Filename 和 ThumbnailPath.- 列表框还定义了一个自定义的 DataTemplate,以便在其下很好地显示图像和文件名.

Here's what I have - a ListBox with an ItemsSource set to a ObservableCollection<T> - where T is my custom class representing a file, containing just 2 DependencyProperties: Filename and ThumbnailPath. - The listbox also has a custom DataTemplate defined, in order to nicely display a image and filename under it.

列表框的目的是显示当前文件夹中的视频文件(在 TreeView 中选择),带有缩略图(异步生成;不是这个问题的一部分).

The purpose of the listbox is to display video files in the current folder (selected in a TreeView), with thumbnails (generated asynchronously; not part of this problem).

所以当我更改TreeView中的文件夹时,ObservableCollection被清除并再次填充,这会自动反映在ListBox项中.

So when I change the folder in the TreeView, the ObservableCollection is cleared and filled up again, which is automatically reflected in the the ListBox items.

问题在于:UI 变得无响应,并且需要几秒钟的时间来更新.同样,缩略图在这里没有意义(我尝试禁用它们).我认为花费最多时间的是构建我的自定义类的 50-100 个实例,以及它们的可视化表示——它必须为每个实例初始化一个 Image 对象.但这只是我的猜测 - 你能确认或排除这种可能性吗?

Here's the problem: The UI becomes unresponsive and it takes up to several seconds to update. Again, thumbnails do not have significance here (I tried disabling them). I think what takes the most time is the construction of 50-100 instances of my custom class, and their visual representation - it has to initialize an Image object for each one. But it's just my guess - could you please confirm or exclude the possibility?

我开始认为 ObservableCollection 可能不适合,因为从我阅读的内容和我尝试的一些内容来看,没有办法异步添加项目,至少如果这些项目是依赖对象.我尝试使用 BackgroundWorker 创建我的类实例并将它们添加到 ProgressChanged 事件处理程序中的集合中,但它引发了异常(一些线程与依赖对象问题).

I'm beginning to think ObservableCollection may not the way to go here, since from what I read and a little from what I tried, there's no way to add items asynchronously, at least if these items are DependencyObjects. I tried creating my class instances with a BackgroundWorker and adding them to the collection in the ProgressChanged event handler, but it throws an exception (some threading vs dependencyobjects problem).

有什么我遗漏的吗?还是通过简单地放弃 ObservableCollection 并编写一个很好的旧异步 for 循环来添加项目会更好?

Is there something that I'm missing? Or would I be better off by simply ditching the ObservableCollection and writing a good old async for loop to add the items?

推荐答案

由于您的 ObservableCollection 绑定到 UI,因此它会在 UI 线程上生成,因此任何进一步的更新(删除/添加/清除)都有位于同一个 UI 线程上.它不允许来自另一个线程的更新.

Since your ObservableCollection is bound to UI hence it gets generated on UI thread so any further updates (delete/add/clear) have to be on the same UI thread. It doesn't allow updates from another thread.

但是,您可以做的是创建类的实例(或在后台线程上进行所有耗时的操作),完成后,使用 UI 的 Dispatcher 在 ObservableCollection 中添加对象像这样的线程 -

However, what you can do is to create an instance of your class (or all time consuming operation on background thread) and once you are done, add the object in ObservableCollection using Dispatcher of your UI thread like this -

App.Current.Dispatcher.BeginInvoke((Action)delegate()
                          {
                              observableCollection.Add(instanceOfYourClass);
                          });

Dispatcher 所做的是将在其关联的线程上操作.因此,该项目将始终添加到 UI 线程上,但可以在后台线程中创建.

What Dispatcher do is put the operation on its associated thread. Hence, the item will always be added on UI thread but can be created in background thread.

这里有几个链接可能会让你前进 - 从 BW 更新 另一个是 here

Here are few links which might get you going - Updating from BW and the other one is here

这篇关于异步添加到 ObservableCollection(或替代方案)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆