如何更新通过一个辅助线程一个ObservableCollection? [英] How do I update an ObservableCollection via a worker thread?

查看:166
本文介绍了如何更新通过一个辅助线程一个ObservableCollection?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的ObservableCollection< A> a_collection; 集合包含'n'项目。每一项看起来是这样的:

I've got an ObservableCollection<A> a_collection; The collection contains 'n' items. Each item A looks like this :

public class A : INotifyPropertyChanged
{

    public ObservableCollection<B> b_subcollection;
    Thread m_worker;
}

基本上,它是所有有线到一个WPF列表视图+详细信息视图控制,显示所选的项目在一个单独的列表视图b_subcollection(双向绑定,在更新的PropertyChanged等)。这个问题表现为我,当我开始实施的线程。整个想法是把整个a_collection使用它的工作线程做工作,然后更新它们各自b_subcollections并有桂实时显示的结果。

Basically, it's all wired up to a WPF listview + a details view control which shows the b_subcollection of the selected item in a separate listview (2-way bindings, updates on propertychanged etc.). The problem showed up for me when I started to implement threading. The entire idea was to have the whole a_collection use it's worker thread to "do work" and then update their respective b_subcollections and have the gui show the results in real time.

当我尝试了,我得到了一个异常说,只有调度线程可以修改一个ObservableCollection和工作才停下来。

When I tried it , I got an exception saying that only the Dispatcher thread can modify an ObservableCollection, and work came to a halt.

谁能解释的问题,以及如何解决它?

Can anyone explain the problem, and how to get around it?

干杯

推荐答案

技术上的问题不是要更新从后台线程的ObservableCollection。问题是,当你这样做,收集引发导致变化在同一线程上的CollectionChanged事件 - 这意味着控制正在从后台线程更新

Technically the problem is not that you are updating the ObservableCollection from a background thread. The problem is that when you do so, the collection raises its CollectionChanged event on the same thread that caused the change - which means controls are being updated from a background thread.

为了从后台线程填充的集合,而控件绑定到它,你可能在为了解决这个从头开始创建自己的集合类型。有一种可能的工作,虽然为你简单的选择。

In order to populate a collection from a background thread while controls are bound to it, you'd probably have to create your own collection type from scratch in order to address this. There is a simpler option that may work out for you though.

发表添加到调用UI线程。

Post the Add calls onto the UI thread.

public static void AddOnUI<T>(this ICollection<T> collection, T item) {
    Action<T> addMethod = collection.Add;
    Application.Current.Dispatcher.BeginInvoke( addMethod, item );
}

...

b_subcollection.AddOnUI(new B());

此方法将立即返回(之前该项目实际上是添加到集合),然后在UI线程上,该项目将被添加到集合,每个人都应该是快乐的。

This method will return immediately (before the item is actually added to the collection) then on the UI thread, the item will be added to the collection and everyone should be happy.

然而,现实是,这种解决办法可能会陷入瘫痪重负载下,因为所有的跨线程活性。一个更有效的解决方案批了一堆物品,并将它们发布到UI线程定期让你不跨线程调用的每一个项目。

The reality, however, is that this solution will likely bog down under heavy load because of all the cross-thread activity. A more efficient solution would batch up a bunch of items and post them to the UI thread periodically so that you're not calling across threads for each item.

的<一个href=\"http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx\">BackgroundWorker类实现的模式,使您可以通过报告其<进度href=\"http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.reportprogress.aspx\">ReportProgress后台操作过程中的方法。进度报告通过ProgressChanged事件UI线程。这可能是你的另一个选择。

The BackgroundWorker class implements a pattern that allows you to report progress via its ReportProgress method during a background operation. The progress is reported on the UI thread via the ProgressChanged event. This may be another option for you.

这篇关于如何更新通过一个辅助线程一个ObservableCollection?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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