C#: Using The BackgroundWorker for Time Consuming/Blocking Tasks
Suppose you have some time-consuming “very useful” function like below
for (var i = 1; i <= 10; i++)
{
Thread.Sleep(TimeSpan.FromMilliseconds(i * 200));
}
If it runs on the UI thread, you will get a “hanged” UI (you can’t click buttons, drag the window etc). To fix that, you can use a BackgroundWorker, its easy. There are 3 main events that you need to handle
DoWork- where all your processing code will goProgressChanged- to do something when progress changes. eg. update progress barRunWorkerCompleted- triggered when background operation (DoWork) has completed, been canceled or raise an exception
The code below is very simple and self-explanatory, ask me in the comments if you have any questions
public MainWindow()
{
InitializeComponent();
#region Worker Stuff
_worker = new BackgroundWorker();
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
// Where your useful, time-consuming, blocking code will go
_worker.DoWork += (s, args) =>
{
for (var i = 1; i <= 10; i++)
{
// handle the cancelation of the task
if (_worker.CancellationPending)
{
args.Cancel = true;
return;
}
_worker.ReportProgress(i * 10);
Thread.Sleep(TimeSpan.FromMilliseconds(i * 200));
}
args.Result = "Done!";
};
// As progress is changed, update the UI
_worker.ProgressChanged += (s, args) =>
{
progBar.Value = args.ProgressPercentage;
txtLog.Text = args.ProgressPercentage + "%";
};
// Handle when the worker is canceled, raises an exception or completes
_worker.RunWorkerCompleted += (s, args) =>
{
if (args.Cancelled)
txtLog.Text = "Canceled";
else if (args.Error != null)
txtLog.Text = args.Error.Message;
else
txtLog.Text = args.Result.ToString();
};
#endregion
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_worker.RunWorkerAsync(); // Starts running code in DoWork()
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
_worker.CancelAsync(); // Cancel the operation. BackgroundWorker.CancelationPending will be set to true
}
A video showing the outcome,
Source Code: on MediaFire