Как повысить скорость и производительность при обновлении и обновлении ObserveableCollection - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь обновить и обновить существующую коллекцию ObservableCollection (с приблизительно 2,3-миллионными объектами в списке) новыми элементами, извлеченными из процедуры SQL. Когда я получаю последние категории, я получаю список с около 72000 наименований. Моя функция, созданная для обновления и обновления коллекции, работает очень хорошо, но на многих обновленных элементах она становится очень медленной и имеет низкую производительность. Как я могу сделать это более эффективным и лучшим способом?

 public async Task UpdateAndRefreshContractMetaDataCollection(ObservableCollection<Category> Categories)
    {
        Type type = typeof(Category);       
        var updatedCategories = await GetLatestUpdatedCategories();

        if (updatedCategories .Count != 0)
        {
            try
            {
                int i = 0;
                foreach (var category in updatedCategories )
                {
                    var categoryCopy = Categories.FirstOrDefault(_ => _.ID== category.ID);
                    if (categoryCopy != null)
                    {
                        i+=1;
                        if (!compareLogic.Compare(categoryCopy , category ).AreEqual)
                        {
                            mapper.Map<Category, Category>(category , categoryCopy );
                        }
                        else
                        {
                            Categories.Add(category );
                        }
                    }
                }
            }
            catch (Exception e) {
                MessageBox.Show("Error updating categories", e.Message);
            }
        }
    }

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Я пробовал с псевдо как рабочий раствор. Это более декларативный способ программирования с использованием Linq, довольно императивный. Извините, я не использовал те же объекты, что и в вашем фрагменте кода. Но попытался сделать это более понятным с моими собственными объектами.

class Program
{
    static void Main(string[] args)
    {
        // Your categires been passed to the method (new categories I assume)
        List<int> categories = new List<int>();

        // Updated categores you retrieved from the database.
        ObservableCollection<int> updatedCategories  = new ObservableCollection<int>();

        // Select all the none matching categires to be added in the <mapper.Map>
        var notmatching = (from u in updatedCategories  join n in categories on u equals n where !Comparer(u, n) select u).ToList();

        // Select all the matching categires to be added in the <categories> collection
        var matching = (from u in updatedCategories  join n in categories on u equals n where Comparer(u, n) select u).ToList();

        // Addiing notmaching categories to you map
        notmatching.ForEach(i => Map(i));

        // Adding matching categies to your existing Categories collection
        categories.AddRange(matching);

    }

    // Represent 'compareLogic.Compare(categoryCopy , category ).AreEqual'
    static bool Comparer(int a, int b) {
        return a == b;
    }
    // Represent mapper.Map<Category, Category>(category , categoryCopy );
    static void Map(int a) {
    }

}
0 голосов
/ 08 января 2019

FirstOrDefault - большая часть узкого места. Для каждого элемента в обновленных категориях вы просматриваете основную коллекцию. Было бы намного быстрее использовать словарь.

Попробуйте это.

public async Task UpdateAndRefreshContractMetaDataCollection(ObservableCollection<Category> Categories)
{
    Type type = typeof(Category);
    var updatedCategories = await GetLatestUpdatedCategories();

    var CatDict = Categories.ToDictionary(c => c.ID);

    if (updatedCategories.Count != 0)
    {
        try
        {
            int i = 0;
            foreach (var category in updatedCategories)
            {
                var categoryCopy = CatDict.ContainsKey(category.ID) ? CatDict[category.ID] : null;
                if (categoryCopy != null)
                {
                    i += 1;
                    if (!compareLogic.Compare(categoryCopy, category).AreEqual)
                    {
                        mapper.Map<Category, Category>(category, categoryCopy);
                    }
                    else
                    {
                        Categories.Add(category);
                    }
                }
            }
        }
        catch (Exception e)
        {
            MessageBox.Show("Error updating categories", e.Message);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...