簡體   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