2014-02-03 3 views
3

У меня есть наблюдаемая коллекция определенного типа Т. Теперь у меня есть слушатель, установленный для сторонней службы, и я получаю объект T, который на самом деле является модификацией существующего объекта в этой наблюдаемой коллекции.Влияние на производительность -> изменение объекта в Observable Collection vs Удаление и добавление нового объекта?

Что мне делать?

1> Найти объект, который был изменен, а затем один за одним изменением всех свойств на вновь полученное значение

ИЛИ

2> просто удалить объект из списка и добавить полученный объект

Примечание: Я могу найти объект из коллекции по запросу LINQ с использованием свойства Id класса T и он уникален для каждого объекта. Вопрос в том, что после того, как я найду объект, я его удалю и добавлю новый, который имеет тот же ID, или я могу изменить существующий?

+2

Могу ли я предложить 3> профиль? – BlackBear

+0

Я бы, ради удобочитаемости, просто заменил элемент в коллекции новым. Но вы всегда можете сделать некоторые тесты самостоятельно, чтобы выяснить, что быстрее. –

+0

@BlackBear Мне любопытно, как это сделать? Будет хорошей новой вещью, чтобы учиться. – Abhinav

ответ

1

Первое решение будет самым быстрым.

Добавление и удаление объекта с ObservableCollection довольно медленно. Операция remove-and-add поднимет 2 CollectionChanged событий.

Проблема с первым решением может быть поиск. Вы можете использовать более сложный алгоритм поиска, или вы можете использовать словарь, чтобы ваши объекты индексировались по id.

Например:

class ComplexObj //Maybe should implement INotifyPropertyChanged 
{ 
    public int Id{get;set;} 
    public string SomeProperty{get;set;} 
} 

Dictionary<int, ComplexObj> lookup = new Dictionary<int, ComplexObj>(); 
ObservableCollection<ComplexObj> myCollection = new ObservableCollection<ComplexObj>(); 

При добавлении элемента в коллекцию убедитесь, чтобы добавить его в словаре тоже:

public void AddNewObj(ComplexObj obj) 
{ 
    lookup.Add(obj.Id, obj); 
    myCollection.Add(obj); 
} 

Затем, когда вам необходимо обновить конкретный объект:

public void Update(ComplexObj obj) 
{ 
    lookup[obj.Id].SomeProperty = obj.SomeProperty; 
} 
+0

Кстати, в complexObj есть около 10 объектов, и у каждого из них есть событие уведомления :( – Debdeep

+0

Что-то иметь в виду и то, что я предполагаю, что у вас есть шаблон пользовательского интерфейса, связанный с этими объектами. значения, чем удаление объекта из коллекции (что, скорее всего, приведет к удалению элементов из дерева визуальных образов) и добавит другое (создание элементов). Возможно, ваш контроль виртуализируется, поэтому поэтому реальный ответ (как уже было сказано) –

+0

@Debdeep Вы должны запустить событие PropertyChanged только в том случае, если действительно изменилось свойство. Если вы этого не сделаете, вы реализуете шаблон неправильным образом. – Alberto

0

Этот ответ в запросе для комментариев от OP.

Вы можете реализовать класс, поддерживающий массовые обновления. Для этого вам необходимо предоставить метод (ы), который устанавливает необходимые значения, обратившись к базовым полям напрямую, а не через свойства. Когда все значения установлены, вы вызываете уведомление для всего объекта. Вот простой класс, чтобы проиллюстрировать идею:

class BindableTypeThatSupportsBulkUpdate : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private string _Text1; 
    public string Text1 
    { 
     get { return _Text1; } 
     set { _Text1 = value; NotifyPropertyChanged(); } 
    } 

    private string _Text2; 
    public string Text2 
    { 
     get { return _Text2; } 
     set { _Text2 = value; NotifyPropertyChanged(); } 
    } 

    private void NotifyPropertyChanged([CallerMemberName]string name = "") 
    { 
     var handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    public void BulkUpdate(string t1, string t2) 
    { 
     _Text1 = t1; 
     _Text2 = t2; 

     // Passing String.Empty as the name causes notification to fire for all the  properties 
     NotifyPropertyChanged(String.Empty); 
    } 
} 

Это упрощен, но вы, вероятно, получите идею в любом случае.

Метод BulkUpdate устанавливает два поля, а затем инициирует уведомление по всему объекту. То есть вы получите только одно обновление, даже если вы обновите несколько значений.

+0

Он удовлетворяет большинству условий моего требования. Как раз один вопрос, будет ли Уведомление уволено один за другим для всех свойств? Если да, тогда пользовательский интерфейс получит отдельное сообщение в насосе сообщений для каждого свойства, и будет ли это быстрее или будет лучше удалить всю строку из пользовательского интерфейса и добавить новую? – Debdeep

+0

Нет только одного уведомления, вызванного уведомлением, используя пустую строку. См. Http://msdn.microsoft.com/en-US/library/windows/apps/hh758320 в разделе «Уведомление об изменении». –

+0

Я думаю, что задаю очень глупый вопрос, но в соответствии с моим пониманием связывание работает как посредник, и каждое свойство Dependency в UI имеет отдельный объект привязки, который привязывается к каждому свойству Model. Теперь, если есть какой-то код, созданный Microsoft для обновления всех свойств зависимостей, как он будет работать внутри страны?Ему нужно будет пройти через все объекты привязки и вызвать функцию для правильного обновления ее значения? Если да, то косвенно снова мы вызываем notifypropertychanged для каждого свойства? – Debdeep

0

Последние обновления (Благодаря @Alberto и @BlackBear за предоставленную мне направления):

я тестировал с XamGrid и наблюдаемой коллекции класса Т, которая имеет 10 свойств связывающихся с сеткой. Каждое свойство вызывает уведомление только в том случае, если его значение изменяется. Также используется словарь-словарь @Alberto.

Подход к удалению и добавлению занимает примерно от 3 до 4 раз, когда в качестве метода модификации требуется х раз. Однако это справедливо, когда ваш фактический объект и измененный объект имеют только разницу в 2 - 3 свойствах (это означает, что не все свойства фактического объекта отличаются от свойств модифицированного объекта, только 2 свойства отличаются друг от друга, поэтому возникает только два уведомления для свойства изменение.)

Если ваш измененный объект имеет около 5 или 6 свойств, повышающих уведомление, то производительность модификации становится такой же, как удаление и добавление строки.

Таким образом, нижняя строка - это больше разница между фактическим и измененным объектом, а больше времени, затраченного на его изменение, и в какой-то момент вы можете подумать о том, чтобы удалить фактический объект и добавить измененный объект.

Для меня стандартный модифицированный объект имеет разницу в 2 - 3 свойствах от фактического объекта и производительность будет лучше для модификации существующего объекта.

Смежные вопросы