wpf 异步添加到 ObservableCollection(或替代方案)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12881489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Asynchronously adding to ObservableCollection (or an alternative)
提问by oli.G
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.
这是我所拥有的 - 一个 ListBox,ItemsSource 设置为 a ObservableCollection<T>- 其中 T 是我的自定义类,表示一个文件,仅包含 2 个 DependencyProperties:Filename 和 ThumbnailPath。- 列表框还定义了一个自定义的 DataTemplate,以便在其下很好地显示图像和文件名。
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 中选择),带有缩略图(异步生成;不是这个问题的一部分)。
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.
所以当我在TreeView中更改文件夹时,ObservableCollection被清除并再次填充,这会自动反映在ListBox项中。
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 thinkwhat 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?
问题是:用户界面变得无响应,更新需要几秒钟的时间。同样,缩略图在这里没有意义(我尝试禁用它们)。 我认为花费最多时间的是构建我的自定义类的 50-100 个实例,以及它们的可视化表示——它必须为每个实例初始化一个 Image 对象。但这只是我的猜测-您能否确认或排除这种可能性?
I'm beginning to think ObservableCollection may not the way to gohere, 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 可能不是这里的方法,因为从我阅读的内容和我尝试的内容来看,无法异步添加项目,至少如果这些项目是 DependencyObjects。我尝试使用 BackgroundWorker 创建我的类实例并将它们添加到 ProgressChanged 事件处理程序中的集合中,但它引发了异常(一些线程与依赖对象问题)。
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 并编写一个很好的旧异步 for 循环来添加项目而变得更好?
回答by Rohit Vats
Since your ObservableCollectionis 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.
由于您ObservableCollection绑定到 UI,因此它是在 UI 线程上生成的,因此任何进一步的更新(删除/添加/清除)都必须在同一个 UI 线程上。它不允许来自另一个线程的更新。
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 Dispatcherof your UI thread like this -
但是,您可以做的是创建类的实例(或在后台线程上创建所有耗时的操作),完成后,使用Dispatcher您的 UI 线程在 ObservableCollection 中添加对象,如下所示 -
App.Current.Dispatcher.BeginInvoke((Action)delegate()
{
observableCollection.Add(instanceOfYourClass);
});
What Dispatcherdo 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.
什么调度员要做的就是把它相关的线程操作。因此,该项目将始终添加到 UI 线程上,但可以在后台线程中创建。
Here are few links which might get you going - Updating from BWand the other one is here
回答by Andreas
With .net 4.5 you can use EnableCollectionSynchronization
使用 .net 4.5,您可以使用 EnableCollectionSynchronization
object lockObj = new object();
BindingOperations.EnableCollectionSynchronization(yourObservableCollection, lockObj);

