首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Silverlight 5中的并发ObservableCollection

Silverlight 5中的并发ObservableCollection
EN

Stack Overflow用户
提问于 2012-03-07 21:03:00
回答 1查看 2.2K关注 0票数 3

在Silverlight 5中,我需要一个线程安全(并发)版本的ObservableCollection。考虑到SL5中缺乏多线程支持,我很难找到一种方法来创建它(没有ReaderWriterLock,也没有Collections.Concurrent,等等)。

当被另一个线程更新时,我需要集合来支持UI绑定。当进程在后台运行时,我无法将所有更新分派到UI线程。理想情况下,后台进程可以根据需要更新集合,并且UI在发生更改时接收通知。这在.NET 4中是可能的,我已经为WPF找到了实现这一目标的方法,而SL却没有。我不能使用WPF示例,因为它们依赖于ReaderWriterLock,AFAIK在SL5中不存在。

任何方向和/或实例都将受到赞赏。

更新

按照Silverlight中使用的异步通信模式(必需),“回调”方法或处理程序在不同的线程上运行。使用TPL (就像我们所做的),这是任务的延续。

因为这段代码运行在不同的线程上,所以任何影响ObservableCollection的语句都必须被封送回UI线程。这意味着进程逻辑和时间现在正在消耗UI线程的资源。

.NET中并发集合的目的是允许生产者和使用者在不同的线程中运行,但是可以无缝地处理集合中的共享数据。SL客户端应用程序中的“生产者”将是异步回调或任务延续,“使用者”是绑定到集合的UI。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-22 17:34:00

我也多次遇到这个问题,这使我走上了你所看到的同一条路。有一个图书馆帮了我很大的忙:

http://ch.codeplex.com/

我使用TinyReaderWriterLock实现了自己的TinyReaderWriterLock,并实现了IList、INotifyCollectionChanged、INotifyPropertyChanged

我用这篇博文作为起点。http://www.deanchalk.me.uk/post/Thread-Safe-Dispatcher-Safe-Observable-Collection-for-WPF.aspx

在我的版本中,我允许在调用线程上执行所有调用,并且只将INotifyCollectionChanged和INotifyPropertyChanged调用封送回UI线程,如下所示:

代码语言:javascript
复制
public void Add(T item)
{
    mSyncLock.LockForWriting();
    innerCollection.Add(item);
    mSyncLock.ReleaseForWriting();

    var index = IndexOf(item);

    OnNotifyPropertyChanged(COUNT_PROPERTY);
    OnNotifyPropertyChanged(INDEXER_PROPERTY);
    OnNotifyCollectionChanged(NotifyCollectionChangedAction.Add, item, index); // This is an overload of OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
}

哪里

代码语言:javascript
复制
protected virtual void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
{
    if (CollectionChanged == null) return;

    ThreadSafeInvoke(() => CollectionChanged(this, e));
}

代码语言:javascript
复制
private static void ThreadSafeInvoke(Action action)
{
    if (Deployment.Current.Dispatcher.CheckAccess())
    {
        action.Invoke();
    }
    else
    {
        Deployment.Current.Dispatcher.BeginInvoke(action);
    }
}

这对我来说很管用。锁定对性能的影响很小,但在大多数情况下并不显着。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9609009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档