- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发的 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/
我已经实现了一个ObservableDictionary(代码粘贴在下面)。如果我使用重载的 ctor 初始化 ObservableDictionary public ObservableDictio
我编写了以下实现(或尝试!)带有通知的字典的类: public partial class ObservableDictionary : Dictionary, INotifyCollectionCh
我正在开发的 C# 应用程序使用 ObservableDictionary。其性能还不够快,无法满足其功能。 ObservableDictionary 的交互速度非常快(删除、添加和更新元素),并且每
我正在尝试使用 ObservableDictionary 的以下实现:ObservableDictionary (C#) . 当我在将字典绑定(bind)到 DataGrid 时使用以下代码: Obs
我将 ObservableDictionary 绑定(bind)到 DataGrid.ItemSource 。我的问题是当我尝试通过数据网格编辑一个值时。我收到异常“此 View 不允许使用 Edit
我有数据绑定(bind)问题。我有一个 WPF (MVVM) 用户控制项目。有Comboboxes和 Labels .每个ComboBox绑定(bind)到 ObservableDictionary
我写了我的public sealed class ObservableDictionary : NotifyPropertyChangedClass, INotifyCollectionChanged
我的应用程序速度存在一些问题,并进行了一些性能分析。结果表明,我的应用程序中有很多时间用于 linq 查询,尤其是模型的 ID。我的想法是创建一个可观察的字典,其中 ID 作为键,模型作为值。这工作得
在包含以下代码的 Visual Studio Community MainPage.xaml.cs 文件中: using System; using System.Collections.Generi
这是插件 https://github.com/jamesfoster/knockout.observableDictionary 这是一个显示我遇到的问题的 fiddle : https://jsf
我是一名优秀的程序员,十分优秀!