我尝试使用进度条在应用程序的初始屏幕上显示。
虽然我很惊讶它只是通过致电progressBar.Value = newValue
而无法工作......
所以我做了一些研究,发现其他繁重的工作可能会阻止UI线程......
Q1
但我真正理解的是,如果UI线程上发生了所有事情,为什么进度条没有刷新呢?
即使我正在做大量工作"像I / O一样,在完成I / O时,我刷新进度条......所以在开始另一个I / O之前不应该刷新进度条???
Q2
好吧,现在让我说我必须使用后台工作人员来完成繁重的工作和UI线程来刷新进度条。
我所做的繁重工作是加载应用程序。它准备了稍后我将需要的对象,在繁重的工作之后,我需要用新的窗口等启动应用程序。
我什么时候做?
我是否添加了RunWorkerCompleted事件处理程序并将应用程序剩余代码的每一部分都放在其中?
然后,事件处理程序中发生的一切,都是UI线程或后台工作者的另一个线程???
非常感谢你的帮助
据我所知,这是我的代码的一部分:
相关进度条:
<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:
上有例外调用线程无法访问此对象,因为另一个线程拥有它
答案 0 :(得分:2)
进度条控件将在获取重绘消息时刷新。但是,当您的慢速方法正在运行时,不会处理消息。
您可以在更改Application.DoEvents()
后调用progressBar.Value
,这将处理所有等待的消息(在极端情况下可能包括点击按钮或关闭您正在使用的表单)。
或致电(也在更改价值后):
progressBar.Invalidate();
progressBar.Update();
答案 1 :(得分:0)
你可以像Mykola Kovalchuk建议的那样做。但是对于繁重的工作,建议使用 BackgroundWorker ,因为它支持取消,您可以在线程处于活动状态时与UI进行交互,例如单击取消按钮。 / p>
Q2:
我什么时候做?
我是否添加了RunWorkerCompleted事件处理程序并将应用程序剩余代码的每一部分都放在其中?
是的,您可以在 BackgroundWorker 忙碌时执行其他有用的工作,并且当RunWorkerCompleted触发时,您可以调用函数来执行您想要的操作。
然后,事件处理程序中发生的一切,都是UI线程或后台工作者的另一个线程???
它确实在主UI线程上运行。更多信息请MSDN。
使用 BackgroundWorker 时,您可以使用 ProgressChanged 事件更新进度条。