2013-02-25 78 views
1

我有一個程序顯示來自日誌文件的行。更高效的日誌過濾器

他們被解析並投入一類叫的logline然後在DataGrid

這裏顯示的是我的過濾功能:

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秒一個記錄200000行。

可以做些什麼來加快速度?

我根據HighCore的建議實現了一個真正的ViewModel。這是稍快,但它仍然是採取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行是從UI獲取數據的可怕方式。你最好創建一個合適的ViewModel來保存這些數據。 – 2013-02-25 14:38:42

回答

1

我寫了一個類似的日誌查看器應用程序,但使用了不同的方法的所有行。

我對您的LogLine等類進行初始解析並將它們存儲在列表中。然後,當用戶選擇各種過濾器組合時,我使用Linq來構建IEnumerable的過濾器匹配,它綁定到一個項目控件(在我的情況下是一個ListView)。如果您願意,您可以使用ObservableCollection並清除/填充相同的結果。

我剛剛測試了一個31MB的文件(240k行),結果在更改過濾器時顯示在一秒之內。