gpt4 book ai didi

c# - 专注于性能的 ObservableDictionary 的替代方案

转载 作者:行者123 更新时间:2023-12-02 09:44:20 25 4
gpt4 key购买 nike

我正在开发的 C# 应用程序使用 ObservableDictionary。其性能还不够快,无法满足其功能。 ObservableDictionary 的交互速度非常快(删除、添加和更新元素),并且每次发生更改时都必须进行排序。我可以使用 ObservableDictionary 的替代方案来关注性能并且仍然能够快速排序吗?

最佳答案

编写自己的代码非常简单,不会在每次添加/更新或删除完成时重新绑定(bind)。正是因为这个原因,我们编写了自己的版本。本质上,我们所做的就是禁用已进行更改的通知,直到处理了集合中的所有对象,然后生成通知。它看起来像这样。正如您所看到的,我们使用 MvvmLight 作为我们的 MVVM 框架库。这将极大地提高性能。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using FS.Mes.Client.Mvvm.MvvmTools.MvvmLight;

namespace FS.Mes.Client.Mvvm.MvvmTools
{
/// <summary>
/// Our implementation of ObservableCollection. This fixes one significant limitation in the .NET Framework implementation. When items
/// are added or removed from an observable collection, the OnCollectionChanged event is fired for each item. Depending on how the collection
/// is bound, this can cause significant performance issues. This implementation gets around this by suppressing the notification until all
/// items are added or removed. This implementation is also thread safe. Operations against this collection are always done on the thread that
/// owns the collection.
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
public class FsObservableCollection<T> : ObservableCollection<T>
{
#region [Constructor]
/// <summary>
/// Constructor
/// </summary>
public FsObservableCollection()
{
DispatcherHelper.Initialize();
}
#endregion

#region [Public Properties]
/// <summary>
/// Gets or sets a property that determines if we are delaying notifications on updates.
/// </summary>
public bool DelayOnCollectionChangedNotification { get; set; }
#endregion

/// <summary>
/// Add a range of IEnumerable items to the observable collection and optionally delay notification until the operation is complete.
/// </summary>
/// <param name="items"></param>
/// <param name="delayCollectionChangedNotification">Value indicating whether delay notification will be turned on/off</param>
public void AddRange(IEnumerable<T> items, bool delayCollectionChangedNotification = true)
{
if (items == null)
throw new ArgumentNullException("items");

DoDispatchedAction(() =>
{
DelayOnCollectionChangedNotification = delayCollectionChangedNotification;

// Do we have any items to add?
if (items.Any())
{
try
{
foreach (var item in items)
this.Add(item);
}
finally
{
// We're done. Turn delay notification off and call the OnCollectionChanged() method and tell it we had a 'dramatic' change
// in the collection.
DelayOnCollectionChangedNotification = false;
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
});
}

/// <summary>
/// Clear the items in the ObservableCollection and optionally delay notification until the operation is complete.
/// </summary>
public void ClearItems(bool delayCollectionChangedNotification = true)
{
// Do we have anything to remove?
if (!this.Any())
return;

DoDispatchedAction(() =>
{
try
{
DelayOnCollectionChangedNotification = delayCollectionChangedNotification;

this.Clear();
}
finally
{
// We're done. Turn delay notification off and call the OnCollectionChanged() method and tell it we had a 'dramatic' change
// in the collection.
DelayOnCollectionChangedNotification = false;
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
});
}

/// <summary>
/// Override the virtual OnCollectionChanged() method on the ObservableCollection class.
/// </summary>
/// <param name="e">Event arguments</param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
DoDispatchedAction(() =>
{
if (!DelayOnCollectionChangedNotification)
base.OnCollectionChanged(e);
});
}

/// <summary>
/// Makes sure 'action' is executed on the thread that owns the object. Otherwise, things will go boom.
/// </summary>
///<param name="action">The action which should be executed</param>
private static void DoDispatchedAction(Action action)
{
DispatcherHelper.CheckInvokeOnUI(action);
}
}
}

关于c# - 专注于性能的 ObservableDictionary 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12357382/

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