c# - 异步添加到 ObservableCollection(或替代方案)

标签 c# .net wpf data-binding observablecollection

这是我的 - 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/

相关文章:

c# - 绑定(bind)到依赖属性,而依赖属性又绑定(bind)到另一个绑定(bind)源

c# - .NET 最小化到托盘并最小化所需资源

wpf - 如何在不给键盘焦点的情况下设置逻辑焦点?

c# - 未处理的异常

c# - 为什么我的 SELECT 与 dataGrid 重复?

.net - session 状态与应用程序状态

C# 图表适合一个选项卡

wpf - 使用 Century 代替 Century Gothic 停止 WPF

c# - DataGridView 限制用户输入

c# - 在 Word Addin 中动态添加 RibbonButtons 会抛出 Collection is readonly