我有一个for
循环(在它自己的线程中运行),我正在计算循环的进度,并且我想在每次更改时显示进度值,但我想在循环外运行消息显示命令,所以它不会t 暂停循环。
我已阅读如何在繁忙的循环中显示进度?,但我不想使用后台工作人员,因为我已经有一个使用启动循环的类的实例(即我不想嵌套后台工作人员)。我假设替代方案是引发和监听事件,但我不确定在这种情况下如何实现。
那么,如何在不使用后台工作人员的情况下解决这个问题呢?
我有一个for
循环(在它自己的线程中运行),我正在计算循环的进度,并且我想在每次更改时显示进度值,但我想在循环外运行消息显示命令,所以它不会t 暂停循环。
我已阅读如何在繁忙的循环中显示进度?,但我不想使用后台工作人员,因为我已经有一个使用启动循环的类的实例(即我不想嵌套后台工作人员)。我假设替代方案是引发和监听事件,但我不确定在这种情况下如何实现。
那么,如何在不使用后台工作人员的情况下解决这个问题呢?
如果是 Winforms,您可以MyForm.BeginInvoke()
使用匿名委托来更新进度显示。BeginInvoke
是异步的,所以它不会阻塞当前线程。
您需要从循环线程中通知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();
由于提供的答案不符合我的要求,因此我对事件进行了一些研究,并按照我最初想要的方式解决了问题。
我在开始循环的类中声明了一个事件:
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;
}