我有一个for
循环(在自己的线程中运行),我正在计算循环的进度,我想在每次更改时显示进度值,但我想运行message display命令在循环之外,所以它不会暂停循环。
我已阅读How do I display progress during a busy loop?,但我不想使用后台工作程序,因为我已经有一个使用启动循环的类实例(即我不想嵌套后台工作程序) 。我假设替代方案是提高和听取事件,但我不确定如何在这种情况下实现。
那么,如何在不使用后台工作者的情况下解决这个问题呢?
答案 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;
}