0

我的应用程序中有一个很长的谓词过滤。我需要以百分比显示确切的进度,但我无法访问Filter中的任何进度。

public ICollectionView viewSource { get; set; }

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

1 回答 1

4

您可以将viewSource.Filter过滤功能包装在BackgroundWorker线程上处理的方法中。如果您能够确定objects要过滤的数量,则可以增加 a 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我在一个线程上开始过滤。开始BackgroundWorkerwithRunWorkerAsync调用该RunFilter方法,该方法又调用LongRunningFilter实际执行过滤的方法(我Thread.Sleep在其中放置了一个以模拟耗时的过滤器)。 LongRunningFilter对 中的每个对象调用一次,ViewSource因此可以用于incrementacounter来告知我们它当前在哪个迭代中。将此与您的已知信息结合使用Maximum,您将获得某种形式的进步。

我意识到这并不完全是您的实际问题的工作方式,但是,它显示了这个概念。

于 2013-10-10T11:15:18.167 回答