[英]Progress bar & background worker
我正在尝试使用进度条在应用程序的初始屏幕上显示。
虽然令我感到惊讶的是,仅通过调用progressBar.Value = newValue
不能正常工作...
所以我做了一些研究,发现其他繁重的工作可能会阻塞UI线程...
Q1
但我真的不明白的是,如果一切都在UI线程上发生的事情,为什么进度条根本没有被刷新?
即使我正在完成I / O之类的“繁重工作”,同时完成一个I / O,我也会刷新进度条...因此,进度条在开始另一个I / O之前也不应刷新吗?
Q2
好了,现在让我们说我必须使用后台工作程序来完成繁重的工作,并使用UI线程刷新进度条。
我要做的繁重工作是加载应用程序。 它准备了以后将需要的对象,在完成繁重的工作之后,我需要使用新窗口等启动应用程序。
我什么时候做?
是否要添加RunWorkerCompleted事件处理程序,并将应用程序其余代码的每个部分都放入其中?
然后,事件处理程序中发生的所有事情,是UI线程还是Background Worker的另一个线程?
非常感谢你的帮助
因此,按照要求,这是我的代码的一部分:
有问题的进度栏:
<ProgressBar Name="progressBar" Height="20" Value="0" Maximum="100" Minimum="0" />
和工人:
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += WorkerOnDoWork;
worker.RunWorkerCompleted += WorkerOnRunWorkerCompleted;
worker.ProgressChanged += SplashManager.onProgress;
worker.RunWorkerAsync();
SplashManager.onProgress方法:
public static void onProgress(object sender, EventArgs e)
{
screen.setProgress(((ProgressChangedEventArgs)e).ProgressPercentage);
}
和屏幕的setProgress方法:
public void setProgress(double progress)
{
progressBar.Value = progress;
}
现在我在progressBar.Value = progress上有一个异常:
调用线程无法访问该对象,因为其他线程拥有它
进度条控件将在刷新消息时刷新。 但是,在运行慢速方法时,不会处理消息。
您可以在更改progressBar.Value
之后调用Application.DoEvents()
,它将处理所有等待的消息(在极端情况下,这可能包括单击按钮或关闭正在使用的表单)。
或致电(也在更改值之后):
progressBar.Invalidate();
progressBar.Update();
您可能会喜欢Mykola Kovalchuk的建议。 但是对于繁重的工作,建议使用BackgroundWorker,因为它支持取消,并且您可以在线程处于活动状态时与UI交互,例如单击“ 取消”按钮。
Q2:
我什么时候做?
是否要添加RunWorkerCompleted事件处理程序,并将应用程序其余代码的每个部分都放入其中?
是的,您可以在BackgroundWorker忙时执行其他有用的工作,并且当RunWorkerCompleted触发器触发时,您可以调用函数来执行所需的操作。
然后,事件处理程序中发生的所有事情,是UI线程还是Background Worker的另一个线程?
它确实在主UI线程上运行。 更多信息,请参见MSDN 。
使用BackgroundWorker时 ,可以使用ProgressChanged事件来更新进度栏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.