簡體   English   中英

使用后台工作程序並更新UI

[英]Using background worker and updating UI

當我需要執行耗時很長的動作時,可以像這樣在BackgroundWorker中調用它,因此它不會凍結UI。

BackgroundWorker bgWorker = new BackgroundWorker();

bgWorker.DoWork += (s, e) => { 
    //Do something long lasting
    for(int i = 0; i < x; i++){

        //Performing action i of x

        //While doing so update the progressbar
        prgBar.Dispatcher.Invoke(() =>{
            prgBar.Value += ((i / x) * 100.0);
        });

    }
};  

bgWorker.RunWorkerCompleted += (s, e) => { 
    //Finish up things
}; 
bgWorker.RunWorkerAsync();

這是更新UI的“方法”還是“未完成”? 相同的問題適用於BackgroundWorker(也許只是啟動一個新線程而不是BackgroundWorker?)

如果需要從后台線程更新某些UI組件,則應使用Dispatcher來編組對主線程的調用。 話雖這么說,您似乎正在嘗試更新一些進度條。 BackgroundWorker類已經提供了一種機制。 因此,您只需在窗體上具有一個ProgressBar控件,然后:

var bgWorker = new BackgroundWorker();

// Specify that this worker supports progress
bgWorker.WorkerReportsProgress = true;

bgWorker.OnProgressChanged += e => 
{
   // This is called on the main thread. It safe to update your UI components here
   myProgressBar.Value = e.ProgressPercentage;
};

bgWorker.DoWork += (s, e) => 
{ 
    // Do something long lasting
    for(int i = 0; i < x; i++) {
        //Performing action i of x

        // While doing so notify the subscribers of the progress event
        var progress = (int)((i / x) * 100.0);
        bgWorker.ReportProgress(progress);
    }
};  

bgWorker.RunWorkerCompleted += (s, e) => 
{ 
    //Finish up things
}; 

bgWorker.RunWorkerAsync();

不它不是。 主要問題是您的進度欄-它位於后台工作線程中,而不是UI線程中。 它也從未真正掛在任何東西上-它在哪里顯示?

正確的方法是擁有一個包含進度條的表單,並在啟動后台工作程序之前在UI線程中打開它(或僅開始對其進行拍攝),然后在完成時將其隱藏。

盡管此刻出現未正確初始化的進度條,但使用Dispatcher的更新邏輯是“正確的”。 但是調用是您必須要做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM