2013-02-25 3 views
1

У меня есть программа, которая отображает строки из файла журнала.Более эффективный журнальный фильтр

Они обрабатываются и помещаются в класс под названием лаглинь затем отображается в сетке

Вот моя функция фильтра:

ICollectionView view = CollectionViewSource.GetDefaultView(this.LogView.ItemsSource); 
bool traceChecked = this.TraceCheckbox.IsChecked.HasValue &&  this.TraceCheckbox.IsChecked.Value; 
bool debugChecked = this.DebugCheckbox.IsChecked.HasValue && this.DebugCheckbox.IsChecked.Value; 
bool infoChecked = this.InfoCheckbox.IsChecked.HasValue && this.InfoCheckbox.IsChecked.Value; 
bool warnChecked = this.WarnCheckbox.IsChecked.HasValue && this.WarnCheckbox.IsChecked.Value; 
bool errorChecked = this.ErrorCheckbox.IsChecked.HasValue && this.ErrorCheckbox.IsChecked.Value; 
string filtertext = this.TextFilterBox.Text; 
view.Filter = o => 
    { 
     LogLine line = o as LogLine; 
     return line != null 
       && (((traceChecked && line.Trace) 
       || (debugChecked && line.Debug) 
       || (infoChecked && line.Info) 
       || (warnChecked && line.Warn) 
       || (errorChecked && line.Error)) 
       && line.Message.Contains(filtertext)); 
    }; 

Эта функция медленно, уже, принимая близко к 5 секунд на log с 200000 строк.

Что можно сделать, чтобы ускорить это?

Я внедрил реальный ViewModel для предложения HighCore. Это немного быстрее, но она по-прежнему занимает 5-6 секунд, чтобы перейти метала всех линий ObservableCollection

ICollectionView view = CollectionViewSource.GetDefaultView(this.LogView.ItemsSource); 
LogViewModel lvm = (LogViewModel)this.DataContext; 
view.Filter = o => 
    { 
     LogLine line = o as LogLine; 
     if (line == null || !line.Message.Contains(lvm.FilterText)) 
      { 
       return false; 
      } 

      switch (line.LogLevel) 
      { 
       case LogViewModel.LogLevel.Trace: 
        return lvm.Trace; 
       case LogViewModel.LogLevel.Debug: 
        return lvm.Debug; 
       case LogViewModel.LogLevel.Info: 
        return lvm.Info; 
       case LogViewModel.LogLevel.Warn: 
        return lvm.Warn; 
       case LogViewModel.LogLevel.Error: 
        return lvm.Error; 
       default: 
        return false; 
      } 
     }; 
+1

Просто комментарий в стороне: первые 7 строк вашего кода являются ужасным способом получения данных из пользовательского интерфейса. вам лучше создать правильный ViewModel для хранения этих данных. –

ответ

1

я написал аналогичное приложение просмотра журнала, но используется другой подход.

Я выполняю первоначальный синтаксический анализ в классе, подобном вашей LogLine, и храните их в списке. Затем, когда пользователь выбирает различные комбинации фильтров, я использую Linq для создания IEnumerable совпадений фильтров, привязанных к элементу управления (в моем случае ListView). Вы можете использовать ObservableCollection и clear/populate с теми же результатами, если хотите.

Я только что протестировал файл размером 31 МБ (строки 240 тыс. Строк), и результаты будут отображаться в течение секунды при смене фильтра.

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