如何在不暂停循环的情况下显示循环的进度?

时间:2012-09-03 10:05:46

标签: c# for-loop backgroundworker progress

我有一个for循环(在自己的线程中运行),我正在计算循环的进度,我想在每次更改时显示进度值,但我想运行message display命令在循环之外,所以它不会暂停循环。

我已阅读How do I display progress during a busy loop?,但我不想使用后台工作程序,因为我已经有一个使用启动循环的类实例(即我不想嵌套后台工作程序) 。我假设替代方案是提高和听取事件,但我不确定如何在这种情况下实现。

那么,如何在不使用后台工作者的情况下解决这个问题呢?

3 个答案:

答案 0 :(得分:1)

如果是Winforms,您可以使用匿名委托进行MyForm.BeginInvoke()更新进度显示。 BeginInvoke是异步的,所以它不会阻塞当前线程。

答案 1 :(得分:0)

您需要从循环线程中通知 LoopWatcher 之类的内容。

public class ProgressEventArgs : EventArgs
{
    public int Number { get; private set; }
    public ProgressEventArgs(int num)
    {
        this.Number = num;
    }
}

public class Worker
{
    public event EventHandler<ProgressEventArgs> ProgressChanged = delegate { };

    public void DoSomething()
    {
        for (int i = 0; i < 10; i++)
        {
            ProgressChanged(this, new ProgressEventArgs(i));
            Thread.Sleep(1000);   //just an example here
        }
    }
}

你可以在Worker.DoSomething中看到,有一个花费时间的循环。我在Worker中添加了一个事件,所以在课外,订阅者可以知道进度已经改变。

var worker = new Worker();
worker.ProgressChanged += (s, e) => Console.WriteLine(e.Number);
Thread t = new Thread(worker.DoSomething);
t.Start();

答案 2 :(得分:0)

由于提供的答案不符合我的要求,我对事件进行了一些研究,并按照我最初想要的方式解决了问题。

我在类中声明了一个启动循环的事件:

public delegate void ProgressChangedEvHandler(int progress);

public event ProgressChangedEvHandler ProgressChanged;

private void OnProgressChanged(int progress)
{
    var handler = ProgressChanged;
    if (handler != null) handler(progress);
}

然后我在循环中调用了这个事件:

for (var index = 0; index < arrayListCount; index++)
{
    var progress = (int) (100*(double) index/(double) arrayListCount);
    OnProgressChanged(progress);
}

然后我在另一个类(在不同的线程上)创建了监听器(LoopClassInstance.ProgressChanged += LoopClassInstance_ProgressChanged;):

private void LoopClassInstance_ProgressChanged(int progress)
{
    toolStripProgressBar1.Value = progress;
}