private void ApplyPendingChanges()
        {
            try
            {
                List <NotifyCollectionChangedEventArgs> allEventArgs = new List <NotifyCollectionChangedEventArgs>();

                this.Log().Debug("Beginning update");
                adapter.PerformBatchUpdates(() =>
                {
                    if (this.Log().Level >= LogLevel.Debug)
                    {
                        this.Log().Debug("The pending changes (in order received) are:");

                        foreach (var pendingChange in pendingChanges)
                        {
                            this.Log().Debug(
                                "Section {0}: Action={1}, OldStartingIndex={2}, NewStartingIndex={3}, OldItems.Count={4}, NewItems.Count={5}",
                                pendingChange.Item1,
                                pendingChange.Item2.Action,
                                pendingChange.Item2.OldStartingIndex,
                                pendingChange.Item2.NewStartingIndex,
                                pendingChange.Item2.OldItems == null ? "null" : pendingChange.Item2.OldItems.Count.ToString(),
                                pendingChange.Item2.NewItems == null ? "null" : pendingChange.Item2.NewItems.Count.ToString());
                        }
                    }

                    foreach (var sectionedUpdates in pendingChanges.GroupBy(x => x.Item1))
                    {
                        var section = sectionedUpdates.First().Item1;

                        this.Log().Debug("Processing updates for section {0}", section);

                        var allSectionEas = sectionedUpdates
                                            .Select(x => x.Item2)
                                            .ToList();

                        if (allSectionEas.Any(x => x.Action == NotifyCollectionChangedAction.Reset))
                        {
                            this.Log().Debug("Section {0} included a reset notification, so reloading that section.", section);
#if UNIFIED
                            adapter.ReloadSections(new NSIndexSet((nuint)section));
#else
                            adapter.ReloadSections(new NSIndexSet((uint)section));
#endif
                            continue;
                        }

                        var updates = allSectionEas
                                      .SelectMany(GetUpdatesForEvent)
                                      .ToList();

                        if (this.Log().Level >= LogLevel.Debug)
                        {
                            this.Log().Debug(
                                "Updates for section {0}: {1}",
                                section,
                                updates
                                .Aggregate(
                                    new StringBuilder(),
                                    (current, next) =>
                            {
                                if (current.Length > 0)
                                {
                                    current.Append(":");
                                }

                                return(current.Append(next));
                            },
                                    x => x.ToString()));
                        }

                        var normalizedUpdates = IndexNormalizer.Normalize(updates);

                        if (this.Log().Level >= LogLevel.Debug)
                        {
                            this.Log().Debug(
                                "Normalized updates for section {0}: {1}",
                                section,
                                normalizedUpdates
                                .Aggregate(
                                    new StringBuilder(),
                                    (current, next) =>
                            {
                                if (current.Length > 0)
                                {
                                    current.Append(":");
                                }

                                return(current.Append(next));
                            },
                                    x => x.ToString()));
                        }

                        foreach (var normalizedUpdate in normalizedUpdates)
                        {
                            switch (normalizedUpdate.Type)
                            {
                            case UpdateType.Add:
                                DoUpdate(adapter.InsertItems, new[] { normalizedUpdate.Index }, section);
                                break;

                            case UpdateType.Delete:
                                DoUpdate(adapter.DeleteItems, new[] { normalizedUpdate.Index }, section);
                                break;

                            default:
                                throw new NotSupportedException();
                            }
                        }
                    }
                }, () =>
                {
                    this.Log().Debug("Ending update");
                    didPerformUpdates.OnNext(allEventArgs);
                });
            }
            finally
            {
                pendingChanges.Clear();
                isCollectingChanges = false;
            }
        }
Esempio n. 2
0
        private void ApplyPendingChanges(int sectionInfoId)
        {
            Debug.Assert(Thread.CurrentThread.ManagedThreadId == this.mainThreadId);
            Debug.Assert(this.isCollectingChanges);
            this.Log().Debug("[#{0}] Applying pending changes", sectionInfoId);

            try {
                adapter.PerformUpdates(
                    () => {
                    if (this.IsDebugEnabled)
                    {
                        this.Log().Debug("[#{0}] The pending changes (in order received) are:", sectionInfoId);

                        foreach (var pendingChange in pendingChanges)
                        {
                            this.Log().Debug(
                                "[#{0}] Section {1}: Action = {2}, OldStartingIndex = {3}, NewStartingIndex = {4}, OldItems.Count = {5}, NewItems.Count = {6}",
                                sectionInfoId,
                                pendingChange.Item1,
                                pendingChange.Item2.Action,
                                pendingChange.Item2.OldStartingIndex,
                                pendingChange.Item2.NewStartingIndex,
                                pendingChange.Item2.OldItems == null ? "null" : pendingChange.Item2.OldItems.Count.ToString(),
                                pendingChange.Item2.NewItems == null ? "null" : pendingChange.Item2.NewItems.Count.ToString());
                        }
                    }

                    foreach (var sectionedUpdates in pendingChanges.GroupBy(x => x.Item1))
                    {
                        var section = sectionedUpdates.First().Item1;

                        this.Log().Debug("[#{0}] Processing updates for section {1}", sectionInfoId, section);

                        var allSectionChanges = sectionedUpdates
                                                .Select(x => x.Item2)
                                                .ToList();

                        if (allSectionChanges.Any(x => x.Action == NotifyCollectionChangedAction.Reset))
                        {
                            this.Log().Debug("[#{0}] Section {1} included a reset notification, so reloading that section.", sectionInfoId, section);
                            adapter.ReloadSections(new NSIndexSet((nuint)section));
                            continue;
                        }

                        var updates = allSectionChanges
                                      .SelectMany(GetUpdatesForEvent)
                                      .ToList();
                        var normalizedUpdates = IndexNormalizer.Normalize(updates);

                        if (this.IsDebugEnabled)
                        {
                            this.Log().Debug(
                                "[#{0}] Updates for section {1}: {2}",
                                sectionInfoId,
                                section,
                                string.Join(":", updates));

                            this.Log().Debug(
                                "[#{0}] Normalized updates for section {1}: {2}",
                                sectionInfoId,
                                section,
                                string.Join(":", normalizedUpdates));
                        }

                        foreach (var normalizedUpdate in normalizedUpdates)
                        {
                            switch (normalizedUpdate.Type)
                            {
                            case UpdateType.Add:
                                DoUpdate(adapter.InsertItems, new[] { normalizedUpdate.Index }, section);
                                break;

                            case UpdateType.Delete:
                                DoUpdate(adapter.DeleteItems, new[] { normalizedUpdate.Index }, section);
                                break;

                            default:
                                throw new NotSupportedException();
                            }
                        }
                    }
                },
                    () => this.Log().Debug("[#{0}] Pending changes applied", sectionInfoId));
            } finally {
                pendingChanges.Clear();
            }
        }