简体   繁体   English

进度栏和后台工作者

[英]Progress bar & background worker

I'm trying to use a progress bar to display on the splash screen of the application. 我正在尝试使用进度条在应用程序的初始屏幕上显示。

Though I was surprised that it didn't work simply by calling progressBar.Value = newValue ... 虽然令我感到惊讶的是,仅通过调用progressBar.Value = newValue不能正常工作...

So I did some research and found out that other heavy work could block the UI thread ... 所以我做了一些研究,发现其他繁重的工作可能会阻塞UI线程...

Q1 Q1

But what I don't really understand is that if everything is happening on the UI thread, why the progress bar is not refreshing at all ? 但我真的不明白的是,如果一切都在UI线程上发生的事情,为什么进度条根本没有刷新?

Even if I was doing "heavy work" like I/O, while finishing an I/O, I refresh the progress bar ... So shouldn't the progress bar refresh before starting another I/O ??? 即使我正在完成I / O之类的“繁重工作”,同时完成一个I / O,我也会刷新进度条...因此,进度条在开始另一个I / O之前也不应刷新吗?

Q2 Q2

Alright, let's now say that I have to use background worker to do the heavy work and UI thread to refresh progress bar. 好了,现在让我们说我必须使用后台工作程序来完成繁重的工作,并使用UI线程刷新进度条。

The heavy work I do is on loading the application. 我要做的繁重工作是加载应用程序。 It prepares object that I will be needed later on, and after heavy work, I need to start the application with a new window etc. 它准备了以后将需要的对象,在完成繁重的工作之后,我需要使用新窗口等启动应用程序。

When do I do it ? 我什么时候做?

Do I add a RunWorkerCompleted event handler and put every part of my remaining code of the application in that ? 是否要添加RunWorkerCompleted事件处理程序,并将应用程序其余代码的每个部分都放入其中?

And then, everything happening in the event handler, is it UI thread or another thread of Background worker ??? 然后,事件处理程序中发生的所有事情,是UI线程还是Background Worker的另一个线程?

Thanks a lot for your help 非常感谢你的帮助

So as asked, here is some part of my code: 因此,按照要求,这是我的代码的一部分:

The progress bar in question : 有问题的进度栏:

<ProgressBar Name="progressBar" Height="20" Value="0" Maximum="100" Minimum="0" />

And the worker : 和工人:

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += WorkerOnDoWork;
worker.RunWorkerCompleted += WorkerOnRunWorkerCompleted;
worker.ProgressChanged += SplashManager.onProgress;
worker.RunWorkerAsync();

The SplashManager.onProgress method: SplashManager.onProgress方法:

public static void onProgress(object sender, EventArgs e)
{
    screen.setProgress(((ProgressChangedEventArgs)e).ProgressPercentage);
}

And the screen setProgress method: 和屏幕的setProgress方法:

public void setProgress(double progress)
{
    progressBar.Value = progress;
}

And now I'm having an exception on progressBar.Value = progress : 现在我在progressBar.Value = progress上有一个异常:

the calling thread cannot access this object because a different thread owns it 调用线程无法访问该对象,因为其他线程拥有它

Progress bar control will refresh when it gets message to repaint. 进度条控件将在刷新消息时刷新。 But while your slow method is running, messages are not processed. 但是,在运行慢速方法时,不会处理消息。

You can either call Application.DoEvents() after changing progressBar.Value , which will process all waiting messages (which in extreme cases could include clicking on buttons or closing form that you are working with). 您可以在更改progressBar.Value之后调用Application.DoEvents() ,它将处理所有等待的消息(在极端情况下,这可能包括单击按钮或关闭正在使用的表单)。

Or call (also after changing value): 或致电(也在更改值之后):

progressBar.Invalidate();
progressBar.Update();

You could do like how Mykola Kovalchuk suggested. 您可能会喜欢Mykola Kovalchuk的建议。 But for heavy work, it is suggested to use BackgroundWorker as it supports cancellation and you can interact with the UI when the thread is active, clicking a cancel button for example. 但是对于繁重的工作,建议使用BackgroundWorker,因为它支持取消,并且您可以在线程处于活动状态时与UI交互,例如单击“ 取消”按钮。

Q2 : Q2:

When do I do it ? 我什么时候做?

Do I add a RunWorkerCompleted event handler and put every part of my remaining code of the application in that ? 是否要添加RunWorkerCompleted事件处理程序,并将应用程序其余代码的每个部分都放入其中?

Yes, You can do other useful work while BackgroundWorker is busy, and when RunWorkerCompleted triggers you can call a function to do what you want. 是的,您可以在BackgroundWorker忙时执行其他有用的工作,并且当RunWorkerCompleted触发器触发时,您可以调用函数来执行所需的操作。

And then, everything happening in the event handler, is it UI thread or another thread of Background worker ??? 然后,事件处理程序中发生的所有事情,是UI线程还是Background Worker的另一个线程?

It does run on the main UI Thread. 它确实在主UI线程上运行。 more information here MSDN . 更多信息,请参见MSDN

When using BackgroundWorker , you can use the ProgressChanged event to update the progress bar. 使用BackgroundWorker时 ,可以使用ProgressChanged事件来更新进度栏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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