簡體   English   中英

如何使用 WPF 后台工作者

[英]How to use WPF Background Worker

在我的應用程序中,我需要執行一系列初始化步驟,這些步驟需要 7-8 秒才能完成,在此期間我的 UI 變得無響應。 為了解決這個問題,我在一個單獨的線程中執行初始化:

public void Initialization()
{
    Thread initThread = new Thread(new ThreadStart(InitializationThread));
    initThread.Start();
}

public void InitializationThread()
{
    outputMessage("Initializing...");
    //DO INITIALIZATION
    outputMessage("Initialization Complete");
}

我已經閱讀了幾篇關於BackgroundWorker文章,以及它應該如何讓我的應用程序保持響應,而不必編寫線程來執行冗長的任務,但是我在嘗試實現它時沒有取得任何成功,誰能告訴我該怎么做使用BackgroundWorker執行此操作?

  1. 添加使用
using System.ComponentModel;
  1. 聲明后台工作人員
private readonly BackgroundWorker worker = new BackgroundWorker();
  1. 訂閱事件:
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
  1. 實現兩種方法:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
  // run all background tasks here
}

private void worker_RunWorkerCompleted(object sender, 
                                           RunWorkerCompletedEventArgs e)
{
  //update ui once worker complete his work
}
  1. 在需要時運行 worker async。
worker.RunWorkerAsync();
  1. 跟蹤進度(可選,但通常有用)

    a) 訂閱ProgressChanged事件並在DoWork使用ReportProgress(Int32)

    b) 設置worker.WorkerReportsProgress = true; (歸功於@zagy)

您可能還想考慮使用Task而不是后台工作人員。

在您的示例中,最簡單的方法是Task.Run(InitializationThread); .

使用任務代替后台工作者有幾個好處。 例如,.net 4.5 中新的 async/await 功能使用Task進行線程處理。 這是有關Task一些文檔https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task

using System;  
using System.ComponentModel;   
using System.Threading;    
namespace BackGroundWorkerExample  
{   
    class Program  
    {  
        private static BackgroundWorker backgroundWorker;  

        static void Main(string[] args)  
        {  
            backgroundWorker = new BackgroundWorker  
            {  
                WorkerReportsProgress = true,  
                WorkerSupportsCancellation = true  
            };  

            backgroundWorker.DoWork += backgroundWorker_DoWork;  
            //For the display of operation progress to UI.    
            backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;  
            //After the completation of operation.    
            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;  
            backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:");  

            Console.ReadLine();  

            if (backgroundWorker.IsBusy)  
            { 
                backgroundWorker.CancelAsync();  
                Console.ReadLine();  
            }  
        }  

        static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)  
        {  
            for (int i = 0; i < 200; i++)  
            {  
                if (backgroundWorker.CancellationPending)  
                {  
                    e.Cancel = true;  
                    return;  
                }  

                backgroundWorker.ReportProgress(i);  
                Thread.Sleep(1000);  
                e.Result = 1000;  
            }  
        }  

        static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)  
        {  
            Console.WriteLine("Completed" + e.ProgressPercentage + "%");  
        }  

        static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)  
        {  

            if (e.Cancelled)  
            {  
                Console.WriteLine("Operation Cancelled");  
            }  
            else if (e.Error != null)  
            {  
                Console.WriteLine("Error in Process :" + e.Error);  
            }  
            else  
            {  
                Console.WriteLine("Operation Completed :" + e.Result);  
            }  
        }  
    }  
} 

另外,參考以下鏈接,您將了解Background的概念:

http://www.c-sharpcorner.com/UploadFile/1c8574/threads-in-wpf/

除了Andrew Orsich所說的,也許你想讀一些關於它的例子。

這是使用后台工作程序和進度條的示例代碼

http://devtoolshed.com/content/c-download-file-progress-bar

這是一個小教程

http://www.dotnetperls.com/backgroundworker

並且在本教程結尾處有另一個progressbar + backgroundworker示例的鏈接。

我發現這個( WPF 多線程:使用 BackgroundWorker 並將進度報告給 UI。鏈接)包含@Andrew 的答案中缺少的其余細節。

我發現非常有用的一件事是工作線程無法訪問 MainWindow 的控件(在它自己的方法中),但是當在主窗口事件處理程序中使用委托時,這是可能的。

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    pd.Close();
    // Get a result from the asynchronous worker
    T t = (t)args.Result
    this.ExampleControl.Text = t.BlaBla;
};

在MSDN中嘗試此鏈接BackgroundWorker類,其中包含如何使用它的示例。

暫無
暫無

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

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