Coder Perfect

WPF Background Worker: How to Use It

Problem

My application requires a series of initialization steps, which take 7-8 seconds to complete and cause my user interface to become unusable. To fix this, I run the startup in a another thread:

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

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

I’ve read a few articles on how the BackgroundWorker should allow me to keep my application responsive without ever having to build a thread to execute lengthy activities, but I’m having trouble implementing it. Could anyone tell me how I would do this using the BackgroundWorker?

Asked by Eamonn McEvoy

Solution #1

using System.ComponentModel;
private readonly BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
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
}
worker.RunWorkerAsync();

Answered by Andrew Orsich

Solution #2

Instead of employing background workers, you might want to consider using Task.

In your case, Task is the simplest way to accomplish this. Run(InitializationThread);.

There are a number of advantages to employing tasks rather than background workers. Task is used for threading in the new async/await features in.net 4.5, for example. Here is some Task documentation. https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task

Answered by Owen Johnson

Solution #3

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);  
            }  
        }  
    }  
} 

Also, if you follow the link below, you will be able to grasp the principles of Background:

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

Answered by Gul Ershad

Solution #4

The rest of the details that are lacking from @Andrew’s answer can be found here (WPF Multithreading: Using the BackgroundWorker and Reporting the Progress to the UI. link).

One thing I discovered was that while the worker thread couldn’t access the MainWindow’s controls (in its own method), it was feasible to do so by utilizing a delegate inside the main window’s event handler.

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;
};

Answered by lko

Post is based on https://stackoverflow.com/questions/5483565/how-to-use-wpf-background-worker