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