BackgroundWorker
Thanks to this class, we can open the window(form) immediately and eg. all data can be loaded in the background. This is usefull becouse basic Windows application runs on a single thread and when we’ve got big list to load on this form. We have to wait until this list and all the others components are loaded then we can display this form.This is sometimes a nuisance. With help coming here BackgroundWorker class – we can upload data asynchronously. I’ll show you how it’s work on example.
Example
I’ll write it on WinForms but it’s looks similar on WPF. We need to hook up a few events.
_backgroundWorker.DoWork += _backgroundWorker_DoWork; _backgroundWorker.ProgressChanged += _backgroundWorker_ProgressChanged; _backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted; _backgroundWorker.WorkerReportsProgress = true; _backgroundWorker.WorkerSupportsCancellation = true;
To the event DoWork we hook up a function that will perform in the background. To ProgressChanged we hook up the code that will show progress and to RunWorkerCompleted a method that informs us of a successful or not successful completion. Propertion WorkerSupportsCancellation allow for the process to be cancelled.
Event DoWork in the loop we sleep the thread for 0.5 seconds and every time we can cancel our operation.
private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i < 100; i++) { if (i != 0) Thread.Sleep(1000); _backgroundWorker.ReportProgress(i); if (_backgroundWorker.CancellationPending) { e.Cancel = true; _backgroundWorker.ReportProgress(0); return; } } _backgroundWorker.ReportProgress(100); }
ProgressChanged informs us of progress.
private void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { label1.Text = $"{e.ProgressPercentage}%"; progressBar1.Value = e.ProgressPercentage; }
And event it informs us that the data upload has finished positive or not.
private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { label1.Text = "Process was cancelled"; } else if (e.Error != null) { label1.Text = "Encountered an error"; } else { label1.Text = "Process was completed"; } }
Also add a button to cancel the action.
private void btn_cancel_Click(object sender, EventArgs e) { if (_backgroundWorker.IsBusy) { _backgroundWorker.CancelAsync(); } }
We run our BackgroundWorker class by calling the method:
_backgroundWorker.RunWorkerAsync();
With this simple way we don’t block main UI thread.
Link to project.