后台操作阻止 ObservableCollection 上的绑定后 UI 更新
我有这个:
- 显示等待动画以“阻止”UI,同时在后台执行加载操作。
- 在加载结束时,我调用一个方法来实例化用户控件并使用绑定(以及 ObservableCollection 等)显示一些数据。
- 此用户控件将显示并且用户可以与其交互,但是 ObservableCollection 似乎卡在另一个线程中因为它不允许向其中添加新项目。
我尝试在BackgroundWorker的Completed事件中更新UI,使用Dispatcher,使用DispatchTimer...所有这些都显示用户控件,但ObservableCollection仍然无法添加。
尝试向集合添加项目的代码位于 UserControl 内部。
确切的错误是:“这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程更改其 SourceCollection”
如果我不在后台进行加载,则不会发生这种情况。
感谢您为此提供任何解决方法。
顺便说一句,尝试使用 Dispatcher 添加项目也不起作用。
换句话说,我想做的是在后台创建 UI 线程中的对象...我知道这可能听起来很愚蠢。
I have this:
- Shows a waiting animation to 'block' the UI while performs a loading operation in the background.
- At the end of the loading I call a method that instances a User Control and displays some data by using Bindings (and ObservableCollection among others)
- This User Control gets displayed and user can interact with it, however the ObservableCollection seems to be stuck in another thread as it doesn't allow to add new items to it.
I've tried to update the UI at the Completed event of a BackgroundWorker, using Dispatcher, using DispatchTimer... all of this displays the User Control, but the ObservableCollection stays of out reach for adding.
The code that tries to add items to the collection is inside the UserControl.
The exact error is: "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread"
This does not happen if I don't do the loading in the background.
Thank you for any workaround for this.
By the way, trying to add the items using Dispatcher doesn't work either.
In other words, what I would like to do is to create an object in the UI Thread while being in the background... I know this may sounds silly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可能需要检查您正在使用哪个
Dispatcher
?就您而言,您可能指的是两个不同的调度员。另外为什么不使用线程安全的可观察集合?
You may have to check which
Dispatcher
you are using? In your case you could be referring to two different dispatchers.Also why not use thread safe observable collection?
通常我会在 UI 线程上创建对象,然后用从后台线程获取的数据填充它们。
例如,
我使用 C# 5.0
async
和await
关键字进行异步操作,但您也可以使用BackgroundWorker
来执行后台工作。您还可以使用 Dispatcher.BeginInvoke() 进行一些较轻的后台工作(例如将数据复制到 MyCollection 中),但对于繁重的工作,我发现它仍然会锁定 UI,因此我更喜欢使用后台线程。
Usually I will create the objects on my UI thread, then populate them with data obtained from a background thread.
For example,
I'm using C# 5.0
async
andawait
keywords for asynchronous operations, but you can also use aBackgroundWorker
that does your background work.You can also use
Dispatcher.BeginInvoke()
for some lighter background work (such as copying data intoMyCollection
), although for heavy work I find it still locks up the UI so I prefer to use background threads.如果视图绑定到该集合,则无法在单独的线程上修改 ObservableCollection 的内容,相反,您可以重写 ObservableCollection 并为其提供支持并在应用程序中使用它。
此示例完全包含您想要的内容 - http: //tomlev2.wordpress.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/
It is not possible to modify the contents of an ObservableCollection on a separate thread if a view is bound to this collection, instead you can override ObservableCollection and provide support for it and use it across your application.
This sample contains exactly what you want - http://tomlev2.wordpress.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/
当涉及到线程和 ui 元素时,要遵循的最重要的规则之一是在 ui 线程上保留 ui 元素实例化,从长远来看可能会给您带来很多麻烦。你当然可以做到。如果您需要从另一个线程更改这些对象,您可以使用调度程序。
(线程模型参考也可能令人感兴趣)< /em>
When it comes to threads and ui-elements one of the most important rules to follow which may safe you a lot of trouble in the long run is to keep ui-element instantiation on the ui-thread. Surely you can manage that. And if you need to change those objects from another thread you can use the Dispatcher.
(The threading model reference may also be of interest)
谢谢大家的帮助...微软的一个人访问该公司(抱歉商业注释)做其他事情,我偷了他并表现出这种行为。大约 2 分钟就找到了问题的根源......我不确定是否真正理解。
碰巧我正在使用 ICollectionView 来显示有问题的 ObservableCollection 的排序/过滤版本。我在类的构造函数中创建了这个 ICollectionView,因此在反序列化时它是在另一个线程中创建的。他建议将此创建移至代码中的更远时间(当读取相关属性时)。这解决了问题。
然而,在另一个线程中创建的 ObservableCollection 现在允许我添加新项目。不知道为什么,但现在可以了。
抱歉这么晚了,再次感谢您。
Thank you everyone for your help... a guy from MS visited the company (sorry for the commercial annotation) to do other things, I stoled him and show this behavior. In a matter of 2 minutes founds the source of the problem... which I'm not sure to really understand.
It happens that I'm using an ICollectionView to display a sorted/filtered version of my problematic ObservableCollection. I was creating this ICollectionView in the constructor of my class, so at the moment of deserialization it was created in another thread. He suggested to move this creation to a further time in code (when the related property gets read). This solved the problem.
However the ObservableCollection, created in that other thread, now lets me add new item. Not sure why, but now it works.
Sorry for being this late and thank you again.