这是我的
- ItemsSource 设置为 ObservableCollection<T>
的列表框
- 其中 T 是代表文件的自定义类,仅包含 2 个 DependencyProperties:Filename 和 ThumbnailPath。
- 列表框还定义了一个自定义的 DataTemplate,以便在其下很好地显示图像和文件名。
列表框的目的是显示当前文件夹中的视频文件(在 TreeView 中选择),带有缩略图(异步生成;不是这个问题的一部分)。
因此,当我更改 TreeView 中的文件夹时,ObservableCollection 会被清除并再次填充,这会自动反射(reflect)在 ListBox 项目中。
这是问题所在:用户界面变得无响应,并且最多需要几秒钟才能更新。同样,缩略图在这里没有意义(我尝试禁用它们)。 我认为花费最多时间的是构建我的自定义类的 50-100 个实例,以及它们的视觉表示 - 它必须为每个实例初始化一个 Image 对象。但这只是我的猜测 - 您能否确认或排除这种可能性?
我开始认为 ObservableCollection 可能不是要走的路,因为从我读到的和我尝试过的一点点来看,没有办法异步添加项目,至少如果这些项目是 DependencyObjects。我尝试使用 BackgroundWorker 创建我的类实例并将它们添加到 ProgressChanged 事件处理程序中的集合,但它抛出异常(一些线程与依赖对象问题)。
有什么我想念的吗?或者我会通过简单地放弃 ObservableCollection 并编写一个很好的旧异步 for 循环来添加项目而变得更好吗?
最佳答案
由于您的 ObservableCollection
绑定(bind)到 UI,因此它在 UI 线程上生成,因此任何进一步的更新(删除/添加/清除)都必须在同一个 UI 线程上。它不允许来自另一个线程的更新。
但是,您可以做的是创建您的类的实例(或后台线程上的所有耗时操作),完成后,使用 UI 的 Dispatcher
将对象添加到 ObservableCollection 中像这样的线程-
App.Current.Dispatcher.BeginInvoke((Action)delegate()
{
observableCollection.Add(instanceOfYourClass);
});
什么 Dispatcher do 是将操作放在其关联的线程上。因此,该项目将始终在 UI 线程上添加,但可以在后台线程中创建。
这里有几个链接可能会让你继续 - Updating from BW另一个是here
关于c# - 异步添加到 ObservableCollection(或替代方案),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12881489/