I have a GridControl
which I populate using a BackgroundWorker
. Then I'm using another BackgroundWorker
to perform some calculations on the dataset which is the datasource of the GridControl
. As I'm trying to do this a cross thread operation on the GridControl
error is thrown. I'm unable to understand that despite not performaing any operation on the gridcontrol itself how the error is generating. (I'm using DevExpress, but that should not change the concept).
Also is there any way I can use one BackgroundWorker
to do different work, i.e. make this code more efficient.
Here is my code:-
public partial class MainForm : XtraForm
{
private BackgroundWorker loadworker = new BackgroundWorker();
private BackgroundWorker calcworker = new BackgroundWorker();
private AutoResetEvent resetEvent = new AutoResetEvent(false);
private Database _db = EnterpriseLibraryContainer.Current.GetInstance<Database>("ConnString");
private DataSet ds;
public MainForm()
{
InitializeComponent();
loadworker.DoWork += loadworker_DoWork;
loadworker.RunWorkerCompleted += loadworker_RunWorkerCompleted;
loadworker.ProgressChanged += loadworker_ProgressChanged;
loadworker.WorkerReportsProgress = true;
calcworker.DoWork += calcworker_DoWork;
calcworker.RunWorkerCompleted += calcworker_RunWorkerCompleted;
calcworker.ProgressChanged += calcworker_ProgressChanged;
calcworker.WorkerReportsProgress = true;
}
private void calcworker_DoWork(object sender, DoWorkEventArgs e)
{
int _cnt = 0;
foreach (DataRow dr in ds.Tables[0].Rows)
{
dr["GROSS"] = (decimal)dr["BASIC"] + (decimal)dr["HRA"] + (decimal)dr["DA"];
_cnt += 1;
}
for (int i = 0; i <= _cnt; i++)
{
Thread.Sleep(100);
calcworker.ReportProgress((100 * i) / _cnt);
}
}
private void calcworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.SetState(true);
this.MainInit();
}
private void calcworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.pgb_DataProgress.Position = e.ProgressPercentage;
}
private void loadworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.pgb_DataProgress.Position = e.ProgressPercentage;
}
private void loadworker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
DbCommand _cmd = _db.GetSqlStringCommand("SELECT Z.EMP_CODE,Z.BASIC,Z.DA,Z.HRA,CAST(0 AS DECIMAL) GROSS FROM Z000000001 Z");
DataSet _data = _db.ExecuteDataSet(_cmd);
for (int i = 0; i <= 10; i++)
{
Thread.Sleep(500);
loadworker.ReportProgress((100 * i) / 10);
}
e.Result = _data;
}
catch (Exception ex)
{
e.Cancel = true;
}
}
private void loadworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.ds = (DataSet)e.Result;
this.gridControl1.DataSource = ds.Tables[0];
this.SetState(true);
this.MainInit();
}
private void btn_FetchData_Click(object sender, EventArgs e)
{
this.gridControl1.DataSource = null;
this.SetState(false);
loadworker.RunWorkerAsync();
}
private void SetState(bool _state)
{
this.btn_Calculate.Enabled = _state;
this.btn_ClearGrid.Enabled = _state;
this.btn_FetchData.Enabled = _state;
}
private void MainInit()
{
this.pgb_DataProgress.Position = 0;
}
private void btn_ClearGrid_Click(object sender, EventArgs e)
{
this.gridControl1.DataSource = null;
}
private void btn_Calculate_Click(object sender, EventArgs e)
{
if (this.gridControl1.DataSource == null)
{
DevExpress.XtraEditors.XtraMessageBox.Show("Data Not loaded", "Message");
return;
}
else
{
this.SetState(false);
calcworker.RunWorkerAsync();
}
}
}