0

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

我已阅读如何在繁忙的循环中显示进度?,但我不想使用后台工作人员,因为我已经有一个使用启动循环的类的实例(即我不想嵌套后台工作人员)。我假设替代方案是引发和监听事件,但我不确定在这种情况下如何实现。

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

4

3 回答 3

1

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

于 2012-09-03T10:14:20.537 回答
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();
于 2012-09-03T10:15:56.403 回答
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;
}
于 2012-09-03T13:34:31.413 回答