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