gpt4 book ai didi

wpf - 快速执行且线程安全的可观察集合

转载 作者:行者123 更新时间:2023-12-03 01:22:59 25 4
gpt4 key购买 nike

ObservableCollection 会针对对其执行的每个操作发出通知。首先,它们没有批量添加或删除调用,其次它们不是线程安全的。

这不会让他们变慢吗?我们不能有更快的替代方案吗?有人说包裹着 ObservableCollectionICollectionView 速度很快?此说法的真实性如何。

最佳答案

ObservableCollection 可以很快,如果它愿意的话。 :-)

下面的代码是线程安全、更快的可观察集合的一个很好的示例,您可以根据自己的意愿进一步扩展它。

using System.Collections.Specialized;

public class FastObservableCollection<T> : ObservableCollection<T>
{
private readonly object locker = new object();

/// <summary>
/// This private variable holds the flag to
/// turn on and off the collection changed notification.
/// </summary>
private bool suspendCollectionChangeNotification;

/// <summary>
/// Initializes a new instance of the FastObservableCollection class.
/// </summary>
public FastObservableCollection()
: base()
{
this.suspendCollectionChangeNotification = false;
}

/// <summary>
/// This event is overriden CollectionChanged event of the observable collection.
/// </summary>
public override event NotifyCollectionChangedEventHandler CollectionChanged;

/// <summary>
/// This method adds the given generic list of items
/// as a range into current collection by casting them as type T.
/// It then notifies once after all items are added.
/// </summary>
/// <param name="items">The source collection.</param>
public void AddItems(IList<T> items)
{
lock(locker)
{
this.SuspendCollectionChangeNotification();
foreach (var i in items)
{
InsertItem(Count, i);
}
this.NotifyChanges();
}
}

/// <summary>
/// Raises collection change event.
/// </summary>
public void NotifyChanges()
{
this.ResumeCollectionChangeNotification();
var arg
= new NotifyCollectionChangedEventArgs
(NotifyCollectionChangedAction.Reset);
this.OnCollectionChanged(arg);
}

/// <summary>
/// This method removes the given generic list of items as a range
/// into current collection by casting them as type T.
/// It then notifies once after all items are removed.
/// </summary>
/// <param name="items">The source collection.</param>
public void RemoveItems(IList<T> items)
{
lock(locker)
{
this.SuspendCollectionChangeNotification();
foreach (var i in items)
{
Remove(i);
}
this.NotifyChanges();
}
}

/// <summary>
/// Resumes collection changed notification.
/// </summary>
public void ResumeCollectionChangeNotification()
{
this.suspendCollectionChangeNotification = false;
}

/// <summary>
/// Suspends collection changed notification.
/// </summary>
public void SuspendCollectionChangeNotification()
{
this.suspendCollectionChangeNotification = true;
}

/// <summary>
/// This collection changed event performs thread safe event raising.
/// </summary>
/// <param name="e">The event argument.</param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
// Recommended is to avoid reentry
// in collection changed event while collection
// is getting changed on other thread.
using (BlockReentrancy())
{
if (!this.suspendCollectionChangeNotification)
{
NotifyCollectionChangedEventHandler eventHandler =
this.CollectionChanged;
if (eventHandler == null)
{
return;
}

// Walk thru invocation list.
Delegate[] delegates = eventHandler.GetInvocationList();

foreach
(NotifyCollectionChangedEventHandler handler in delegates)
{
// If the subscriber is a DispatcherObject and different thread.
DispatcherObject dispatcherObject
= handler.Target as DispatcherObject;

if (dispatcherObject != null
&& !dispatcherObject.CheckAccess())
{
// Invoke handler in the target dispatcher's thread...
// asynchronously for better responsiveness.
dispatcherObject.Dispatcher.BeginInvoke
(DispatcherPriority.DataBind, handler, this, e);
}
else
{
// Execute handler as is.
handler(this, e);
}
}
}
}
}
}

此外,位于 ObservableCollection 之上的 ICollectionView 会主动感知更改,并与任何其他源列表相比相对较快地执行过滤、分组和排序。

同样,可观察集合可能不是更快数据更新的完美答案,但它们的工作做得很好。

关于wpf - 快速执行且线程安全的可观察集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7687000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com