繁体   English   中英

进度栏和后台工作者

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM