Hi Friends, Today we will discuss in this article how to use Backgroundwalker control in C # and load records from the database table.
Introduction
BackgroundWorker is used to execute Intensive tasks (time-consuming) in Separate Thread so the User Interface (UI) does not freeze.
As the tasks are running in the background and might take a long time, it is necessary to show some custom messages and update the UI when the work is done.
Adding BackgroundWorker Control
To add a BackgroundWorker control on to the Form, Simply drag and drop the control from Tool-box on to the Form or double-click the control in Tool-box to add it to the Form.
The Control is then placed on to the System-tray
The BackgroundWorker control is highlighted in the circle which is placed on to the System tray.
BackgroundWorker Properties
The properties of a BackgroundWorker which you need to know are:
WorkerReportsProgress – Used to indicate Progress when a task is running.
WorkerSupportsCancellation – Indicates whether the background task can be cancelled.
IsBusy - Indicates that the background worker is performing an Asynchronous Operation/background task or not.
CancellationPending – This Indicates that the application has requested the cancellation of the background task.
BackgroundWorker Methods
The methods associated with a BackgroundWorker are
RunWorkerAsync – To Start the background task
CancelAsync - To Stop the background task/Thread
ReportProgress – To Report Progress
BackgroundWorker Events
These are three events associated with a BackgroundWorker
The DoWork event does the costly work of executing the background Thread.
ProgressChanged
The ProgressChanged event reports the progress done by the Thread. The ProgressChanged event is raised from the DoWork Event using ReportProgress() Method.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// To report BackgroundWorker Progress
}
Then ProgressChangedEventArgs e contains properties e.ProgressPercentage and e.UserState
e.ProgressPercentage – Gets the progress percentage of the background task that is sent as a parameter in ReportProgress() Method of the DoWork Event
e.UserState – Gets the user state that is sent as part of ReportProgress() Method from DoWork Event
RunWorkerCompleted
The event is executed when the BackgroundWorker has completed the Task. The event is also triggered when the BackgroundWorker is failed to do the task assigned or intentionally cancelling the task.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Executed Up on Completion of BackgroundTask/ Failure/ Cancellation of Operation
}
The RunWorkerCompletedEventArgs e has
e.Cancelled – Indicates that the BackgroundWorker Operation has been Cancelled.
e.Error – Error Occurred in the background Process execution
e.Result – Indicates the Result of the background Process execution.
BackgroundWorker Example
Program
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Threading;
namespace BackGroundWorkerExample
{
public partial class frmRetrive : Form
{ SqlCommand Sqlcmd;
string ConnString = "Data Source=ServerName; User id =YourDBUserName; Password =DBPwd;";
int TotalRecords;
public frmRetrive()
{ InitializeComponent();
// To report progress from the background worker we set this property
backgroundWorker1.WorkerReportsProgress = true;
}
private void frmRetrive_Load(object sender, EventArgs e)
{
btCancel.Enabled = false;
statusStrip1.Visible = false;
toolStripStatusLabel1.Visible = false;
dataGridView1.ColumnCount = 2;
dataGridView1.Columns[0].Name = "Fiche No.";
dataGridView1.Columns[0].Width = 150;
dataGridView1.Columns[1].Width = 150;
dataGridView1.RowHeadersWidth = 21;
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing; dataGridView1.ColumnHeadersHeight = 23;
dataGridView1.Columns[1].Name = "Employee Name";
}
private void btExecute_Click(object sender, EventArgs e)
{
statusStrip1.Visible = true;
toolStripStatusLabel1.Visible = true;
toolStripProgressBar1.Maximum = GetTotalRecords();
if (!backgroundWorker1.IsBusy)
{
RetriveTableData TObj = new RetriveTableData();
dataGridView1.Rows.Clear();
backgroundWorker1.RunWorkerAsync(TObj);
btExecute.Enabled = false;
btCancel.Enabled = true;
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
RetriveTableData Obj = (RetriveTableData)e.Argument;
string SqlcmdString = "SELECT C_FICH,C_SITE FROM XT_FICH";
SqlDataReader reader;
int i = 1;
try {
using (SqlConnection conn = new SqlConnection(ConnString))
{
Sqlcmd = new SqlCommand(SqlcmdString, conn);
conn.Open();
reader = Sqlcmd.ExecuteReader();
if (reader.HasRows)
{ while (reader.Read())
{
//int.Parse(reader["NO_IND"].ToString()); Obj.EmpId = reader["C_FICH"].ToString();
Obj.EmpName = reader["C_SITE"].ToString();
Thread.Sleep(100);
// To Report progress.
backgroundWorker1.ReportProgress(i,Obj);
if (backgroundWorker1.CancellationPending)
{ // Set the e.Cancel flag so that the WorkerCompleted event // knows that the process was cancelled. e.Cancel = true; backgroundWorker1.ReportProgress(0); return;
}
i++;
}
conn.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
if (!backgroundWorker1.CancellationPending)
{ RetriveTableData Obj = (RetriveTableData)e.UserState;
dataGridView1.Rows.Add(Obj.EmpId.ToString(),Obj.EmpName.ToString());
toolStripProgressBar1.Value = e.ProgressPercentage;
toolStripStatusLabel1.Text = "Processing row.. " + e.ProgressPercentage.ToString() + " of " +TotalRecords;
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled)
{
toolStripStatusLabel1.Text = "Cancelled by User Intentionally...";
toolStripProgressBar1.Value = 0;
}
// Check to see if an error occurred in the background process.
else if (e.Error != null)
{
toolStripStatusLabel1.Text = e.Error.Message;
}
else
{
// BackGround Task Completed with out Error
toolStripStatusLabel1.Text = " All Records Loaded...";
}
}
private int GetTotalRecords()
{
SqlConnection con;
SqlCommand cmd;
try
{
using (con = new SqlConnection(ConnString))
{
cmd = new SqlCommand("SELECT COUNT(*) FROM XT_FICH", con);
con.Open();
TotalRecords = int.Parse(cmd.ExecuteScalar().ToString());
con.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return TotalRecords;
}
private void btCancel_Click(object sender, EventArgs e)
{ if (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
btCancel.Enabled = false;
btExecute.Enabled = true;
}
}
public class RetriveTableData
{
public string EmpId;
public string EmpName;
}
private void frmRetrive_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
if (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
btCancel.Enabled = false;
btExecute.Enabled = true;
} }
}
}
}
Starting a BackgroundWorker Task
The BackgroundWorker DoWork is fired when the RunWorkerAsync method is called
private void btStart_Click(object sender, EventArgs e)
{
statusStrip1.Visible = true;
toolStripStatusLabel1.Visible = true;
toolStripProgressBar1.Maximum = GetTotalRecords();
if (!backgroundWorker1.IsBusy)
{
RetriveTableData TObj = new RetriveTableData();
dataGridView1.Rows.Clear();
// Start the BackGround Thread to Execute
backgroundWorker1.RunWorkerAsync(TObj);
btStart.Enabled = false;
btCancel.Enabled = true;
}
}
The btStart_Click Event here calls the RunWorkerAsync() Method to fire the DoWork Event of the BackgroundWorker which executes the time-consuming task at the background Thread.
Here pass RunWorkerAsync() an Object of RetriveTableData class.
/// <summary>
/// Trial Class for Example
/// </summary>
public class RetriveTableData
{
public string EmpId;
public string EmpName;
}
In the above code, we check to see that the BackgroundWorker is performing any task in the background using the backgroundWorker1. IsBusy Property. If not, we call the RunWorkerAsync Method to start executing the Thread.
BackgroundWorker Thread
The actual execution of the Thread Starts here
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
RetriveTableData Obj = (RetriveTableData)e.Argument;
string SqlcmdString = "SELECT C_FICH,C_SITE FROM XT_FICH";
SqlDataReader reader;
int i = 1;
try
{
using (SqlConnection conn = new SqlConnection(ConnString))
{
Sqlcmd = new SqlCommand(SqlcmdString, conn);
conn.Open();
reader = Sqlcmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
//int.Parse(reader["NO_IND"].ToString());
Obj.EmpId = reader["C_FICH"].ToString();
Obj.EmpName = reader["C_SITE"].ToString();
Thread.Sleep(100);
// To Report progress.
backgroundWorker1.ReportProgress(i,Obj);
if (backgroundWorker1.CancellationPending)
{
// Set the e.Cancel flag so that the WorkerCompleted event
// knows that the process was cancelled.
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
i++;
}
conn.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The e.Argument in RetriveTableData Obj = (RetriveTableData)e.Argument contains the Parameter reference to the BackgroundWorker that is received by RunWorkerAsync which we cast it explicitly to type RetriveTableData.
Then, we establish the connection with the Specified DataSource and read records from the Database using the SqlDataReader class. The reader.Read() reads/retrieve the rows one-by-one from the Database table.
Next, we Report the progress using the ReportProgress Method of the BackgroundWorker where we pass it an int variable I and RetriveTableData Obj which has the record number and the Obj contains the value of the record that is read recently.
Each time we increment the variable I to 1 to indicate the number of records being read.
// To Report progress.
backgroundWorker1.ReportProgress(i,Obj);
BackgroundWorker Progress
The ProgressChanged event of BackgroundWorker is fired when; the ReportProgress is called in from the DoWork Event.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (!backgroundWorker1.CancellationPending)
{
//Gets the user state that is sent as part of ReportProgress() Method from DoWork Event
RetriveTableData Obj = (RetriveTableData)e.UserState;
//Add the data to the dataGridView1
dataGridView1.Rows.Add(Obj.EmpId.ToString(),Obj.EmpName.ToString());
toolStripProgressBar1.Value = e.ProgressPercentage;
toolStripStatusLabel1.Text = "Processing row.. " + e.ProgressPercentage.ToString() + " of " +TotalRecords;
}
}
Here we get the UserState and add the data to the dataGridView1 and we set the toolStripProgressBar1 value to the progress percentage of the background task that is sent as parameter in ReportProgress() Method in DoWork Event.
Completion of Background Task
Upon, completion or Cancellation or failure of the Task the following event is raised.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
toolStripStatusLabel1.Text = "Cancelled by User Intentionally...";
toolStripProgressBar1.Value = 0;
}
// Check to see if an error occurred in the background process.
else if (e.Error != null)
{
toolStripStatusLabel1.Text = e.Error.Message;
}
else
{
// BackGround Task Completed with out Error
toolStripStatusLabel1.Text = " All Records Loaded...";
}
}
If the BackgroundWorker Task is cancelled by the Application, then e. Cancelled is set to true and the block of code in it executed, The cancellation of Task is Sent from the DoWork Event to the RunWorkerCompleted Event. In DoWork Event, the piece of code to check that the Process was cancelled is
if (backgroundWorker1.CancellationPending)
{
// Set the e.Cancel flag so that the WorkerCompleted event
// knows that the process was cancelled.
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
Cancellation of Background Task
The background Process is cancelled by the CancelAsync Method of the BackgroundWorker.
//To see that background Process is running a Process
if (backgroundWorker1.IsBusy)
{
// Stop the Background Thread execution
backgroundWorker1.CancelAsync();
btCancel.Enabled = false;
btStart.Enabled = true;
}
the execution of Thread by calling the CancelAsync Method.
Conclusion
We have seen how to work with BackgroundWorker Control in C# Windows Form that executes an asynchronous Operation on a Separate Thread, and the Properties and events associated with a BackgroundWorker.
Shakir Ali
17-Oct-2018Thanks for sharing this valuable information. Could you please share the complete working project i have a problem in code. Thanks in advance.
Anmol Rathod
04-Nov-2017would this method work for binding data to the ListView control using SQLite in windows forms ?
Manmohan Jha
26-Feb-2013Regard
Manmohan Jha
John Smith
25-Feb-2013