2013-10-10 103 views
0

我的应用程序中有一个很长的谓词过滤器。 我需要以百分比显示确切的进度,但我有权访问筛选器内的任何进度。在长时间运行的过滤器谓词中的显示进度

public ICollectionView viewSource { get; set; } 

viewSource = CollectionViewSource.GetDefaultView(Photos); 
// this line takes 30 seconds 
viewSource.Filter = i => (... & ... & .... long list of conditions) 

回答

4

你可以在其中对BackgroundWorker线程处理的方法,换你viewSource.Filter过滤功能。如果您可以确定要过滤的objects的数量,则可以增加一个counter,该数字可以与启动计数一起用于提供进度。

编辑:

using System; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Threading; 
using System.Windows; 
using System.Windows.Data; 
using System.Windows.Threading; 

public partial class MainWindow : Window 
{ 
    private readonly Random random = new Random(); 
    private BackgroundWorker backgroundWorker; 
    private ObservableCollection<int> CollectionOfInts { get; set; } 
    private ICollectionView ViewSource { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.CollectionOfInts = new ObservableCollection<int>(); 
     var nextRandom = this.random.Next(1, 200); 
     for (var i = 0; i <= nextRandom + 2; i++) 
     { 
      this.CollectionOfInts.Add(this.random.Next(0, 2000)); 
     } 

     this.ViewSource = CollectionViewSource.GetDefaultView(this.CollectionOfInts); 
     this.ProgressBar.Maximum = this.CollectionOfInts.Count; 
    } 

    private void RunFilter() 
    { 
     this.ViewSource.Filter = LongRunningFilter; 
    } 

    private bool LongRunningFilter(object obj) 
    { 
     try 
     { 
      Application.Current.Dispatcher.BeginInvoke(
       DispatcherPriority.Normal, 
       new Action(() => this.ProgressBar.Value++) 
       ); 
      var value = (int) obj; 
      Thread.Sleep(3000); 
      return (value > 5 && value < 499); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
     return false; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     try 
     { 
      this.ProgressBar.Value = 0; 
      this.backgroundWorker = new BackgroundWorker(); 
      this.backgroundWorker.DoWork += delegate { RunFilter(); }; 
      this.backgroundWorker.RunWorkerAsync(); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 
} 

这里的基本原则是,我知道我有多少objects有过滤(this.CollectionOfInts.Count),所以这是我Maximum值(100%)。我开始在BackgroundWorker线程上进行过滤。使用RunWorkerAsync开始BackgroundWorker调用RunFilter方法,该方法又调用LongRunningFilter实际执行过滤(我在此放置了一个Thread.Sleep以模拟耗时的过滤器)。 LongRunningFilter对于ViewSource中的每个对象都被调用一次,因此可用于increment a counter来通知我们当前正在进行哪个迭代。将此与您已知的Maximum一起使用,您有一种进步的形式。

我意识到这不完全是你的实际问题的工作原理,但是,它显示了这个概念。

+0

如何(或在哪里)增加“计数器”? @Veleous – AVEbrahimi

+0

@Avebrahimi我为您的评论添加了一个示例。 – 2013-10-10 18:16:26

相关问题