如何使用IEnumerable实现进度?

时间:2011-03-22 21:31:36

标签: c# .net wpf progress-bar ienumerable

我有一个循环遍历IEnumerable集合的方法,并将它们中的每一个传递给另一个方法。类似的东西:

void Run (object item)
{
    foreach(var method in this.Methods)
        method (item);
)

如何实现将在进度条中反映的一系列进度?如果它在这个方法中直接编码,我可以很容易地做到这一点,但是这个方法包含在ViewModel之外的类型中,我当然可以调用它。

我只是不知道如何实现它并从该方法中获取它并通过将其传递给ViewModel等来反映UI中的更改。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

我最终做的是传递用于报告进度的委托。这提供了非常好的解耦。委托可以实现为lambda函数,直接设置表单上的进度。

void Run (object item, Action<float> progress)
{ 
    int total = MethodCollection.Count; 
    int index = 0;
    foreach(var method in MethodCollection)
    {
        method (item);
        progress(index/(float)total);
    }
)

对于长时间运行的任务,我会在使用BackgroundWorker的单独线程上执行此操作,后者具有用于进度报告的内置挂钩。

答案 1 :(得分:2)

我会通过使用如下事件来解决这个问题。

public class ViewModel : ViewModelBase
{
    private int m_CurrentProgress;
    private int m_MethodCount;

    // Bind this to the progress bar
    public int CurrentProgress
    {
        get { return m_CurrentProgress; }
        set
        {
            m_CurrentProgress = value;
            OnPropertyChanged("CurrentProgress");
        }
    }

    // Bind this to the progress bar
    public int MethodCount
    {
        get { return m_MethodCount; }
        set
        {
            m_MethodCount = value;
            OnPropertyChanged("MethodCount");
        }
    }

    private void MethodExecuted(object sender, EventArgs e)
    {
        CurrentProgress++;
    }

    public void Run()
    {
        var c = new ExternalClass();
        MethodCount = c.Methods.Count;
        c.MethodExecuted += MethodExecuted;

        c.Run(null);
    }
}

public class ExternalClass
{
    public List<object> Methods { get; set; }

    public event EventHandler<EventArgs> MethodExecuted;

    public void InvokeMethodExecuted(EventArgs e)
    {
        EventHandler<EventArgs> handler = MethodExecuted;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    public void Run(object item)
    {
        foreach (var method in Methods)
        {
            method(item);

            InvokeMethodExecuted(null);
        }
    }
}