【问题标题】:Windows Phone 8.1 (RT) app with SQLite Db which contains 67k elements. Works slowly带有 SQLite Db 的 Windows Phone 8.1 (RT) 应用程序,其中包含 67k 个元素。工作缓慢
【发布时间】:2015-11-09 15:09:12
【问题描述】:

我为“Windows Phone 8.1”开发了一个应用程序,我正在使用一个包含 4700 个项目的数据库。在“Windows Store App 8.1/10 (Desktop/Tablet)”应用程序运行速度很快,但“Windows Phone 8.1”可以看到“UI”运行缓慢且滞后。这里是性能分析器的分析。

当应用程序启动“OnLaunching”方法时,我将数据从 sqlite 存储库加载到静态类中的静态属性“IEnumerable”。

await Task.Run(async () =>
    {
        if (InstanceMessageService.AllHolidays == null)
            {
                InstanceMessageService.AllHolidays = _repository.GetAll();
                InstanceMessageService.AllCountries = await Task.Run(() =>
                    InstanceMessageService.AllHolidays.GroupBy(holiday => holiday.Country)
                        .Select(x => x.First().Country)
                        .Select(s => new Country()
                        {
                            Title = s,
                            FirstLetter = s[0].ToString()
                        }).ToList()
                    );

                    if (!InstanceMessageService.AllHolidays.Any() || !InstanceMessageService.AllCountries.Any())
                    {
                        throw new Exception("Cannot load SQLite data"); 
                    }
                }
            });

这里是InstanceMessageService

public static class InstanceMessageService
{
    public static IEnumerable<Holiday> AllHolidays { get; set; } 
    public static IEnumerable<Country> AllCountries { get; set; }
    ...
}

现在静态属性中包含 4700 个假日项目(在内存中)和国家/地区的 171 个项目。我认为这不是好方法。

这是我的 CalendarsPage 的 ViewModel 代码。 CalendarsPage 提供今天、明天或从日历控件中选择的具体日期的假期数据。

public class CalendarPageViewModel : INotifyPropertyChanged
    
        public IEnumerable<Holiday> Holidays
        {
            get { return _holidays; }
            set
            {
                _holidays = value;
                OnPropertyChanged("Holidays");
            }
        }

        public ObservableCollection<Holiday> TodayHolidays
        {
            get { return _todayHolidays; }
            set
            {
                _todayHolidays = value;
                OnPropertyChanged("TodayHolidays");
            }
        }

        public ObservableCollection<Holiday> TomorrowHolidays
        {
            get { return _tomorrowHolidays; }
            set
            {
                _tomorrowHolidays = value;
                OnPropertyChanged("TomorrowHolidays");
            }
        }

        public ObservableCollection<Holiday> SelectedDateHoliday
        {
            get { return _selectedDateHoliday; }
            set
            {
                _selectedDateHoliday = value;
                OnPropertyChanged("SelectedDateHoliday");
            }
        }

        public CalendarPageViewModel()
        {
            Task task = InitCollections();
            InitCommands();
        }
     
       **// Slowly magic here**

        private async Task InitCollections()
        {
            Holidays = InstanceMessageService.AllHolidays;
            TomorrowHolidays = new ObservableCollection<Holiday>(await Task.Run(() => Holidays.Where(holiday => holiday.Date == DateTime.Now.AddDays(1).Date.ToString("MMM d")).Select(holiday => holiday)));
            TodayHolidays = new ObservableCollection<Holiday>(await Task.Run(() => Holidays.Where(holiday => holiday.Date == DateTime.Now.Date.ToString("MMM d")).Select(holiday => holiday)));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

存储库类代码

public class HolidaysRepository : IRepository<Holiday>
    {
        private readonly IDatabaseConnection _databaseConnection;
        public HolidaysRepository(IDatabaseConnection databaseConnection)
        {
            _databaseConnection = databaseConnection;
        }

        public List<Holiday> GetAll()
        {
            return _databaseConnection.Connection.Table<Holiday>().ToList();
        }

        public void AddOrUpdate(Holiday entity)
        {
            if (_databaseConnection.Connection.Table<Holiday>().FirstOrDefault(item => item.Id == entity.Id) !=
                null)
            {
                Update(entity);
            }
            else
            {
                Add(entity);
            }
        }

        public void Add(Holiday entity)
        {
            _databaseConnection.Connection.Insert(entity);
        }

        public void Update(Holiday entity)
        {
            _databaseConnection.Connection.Update(entity);
        }

        public void Delete(Holiday entity)
        {
            _databaseConnection.Connection.Delete(entity);
        }

        public void Clean()
        {
            _databaseConnection.Connection.DeleteAll<Holiday>();
        }
    }

这可能很重要,在应用程序中我使用“Ninject”作为“ServiceLocator”。

如何提高应用程序的速度?如何减少使用的 RAM 量?如果 4700 个元素使应用程序运行缓慢而 UI 运行缓慢,那么我认为 67,000 个项目将没有足够的 RAM。

【问题讨论】:

  • 我认为您不想一次加载所有数据。为什么不只加载今天、明天和所选日期的假期。或者,如果您的应用具有月度视图,则只需加载上个月、当前月和下个月的数据。
  • 感谢您的回复。我尝试这样做,但 UI 的速度并没有变得更快。也许我应该在加载数据时添加动画。也许 sqlite orm 变慢了?我没有使用干净的 sql 查询。谢谢

标签: c# sqlite windows-phone-8.1 windows-store-apps


【解决方案1】:

当加载大量数据所需的时间超出您的预期时,最简单的解决方案通常是加载更少的数据。

您真的需要在数据库中加载所有假期吗?
你不能只加载你需要的特定日期吗?例如,只需默认加载今天和明天的任何假期,然后查找用户选择的任何其他特定日期。

如果您不需要所有假期,但确实必须加载所有国家/地区,那么单独存储这些列表可能比加载所有假期来提取国家/地区更快。

在数据库中查询数据时,您应该确保有适当的索引以加快查找速度。

还可能值得查看您对数据的索引,以便您可以直接从数据库中搜索它,而不是将其全部加载到您可能会搜索的列表中。

【讨论】:

  • 你好,马特,谢谢你的回复。你能建议我在哪里可以阅读关于 Windows 商店/电话应用程序的 SQLite 索引吗?或者,如果它对 Android 无关紧要。我对数据库只有一点经验。我今天、明天和当月的预加载数据的应用程序与以前一样工作,我的意思是慢慢地。可能我需要在页面上添加进度条动画。谢谢=)
  • 在我的假期应用程序中,我添加了三个部分。第一部分显示我们今天有哪些假期,明天和日历控件供用户选择。第二部分通过查询(如假期名称)从所有假期中搜索。第三部分带有国家列表和搜索查询字段以过滤国家列表。我的意思是用户可以在此部分中手动查找国家/地区列表滚动或通过搜索查询与国家/地区名称。
猜你喜欢
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
相关资源
最近更新 更多