代码之家  ›  专栏  ›  技术社区  ›  Soham Dasgupta

使用BackgroundWorker使用网格

  •  0
  • Soham Dasgupta  · 技术社区  · 14 年前

    我有一个 GridControl 我用一个 BackgroundWorker . 然后我用另一个 背景工作者 对数据集执行一些计算,该数据集是 网格控件 . 当我尝试在 网格控件 引发错误。我无法理解,尽管没有对GridControl本身执行任何操作,但错误是如何生成的。(我正在使用devexpress,但这不会改变概念)。

    还有什么我能用的方法吗 背景工作者 做不同的工作,也就是说,提高代码的效率。

    这是我的密码:

    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();
                }
            }
    
        }
    
    2 回复  |  直到 14 年前
        1
  •  0
  •   VinayC    14 年前

    简而言之,除了在其上创建控件的UI线程外,您不能访问其他线程上的控件。因此,任何控件方法/属性调用都必须使用 Control.Invoke 方法。

    例如,在您的情况下 loadworker_RunWorkerCompleted 将在工作线程上调用事件处理程序,访问控件属性将引发错误。您需要将事件处理程序修改为

        private void loadworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            System.Action a = () => {
              this.ds = (DataSet)e.Result;
              this.gridControl1.DataSource = ds.Tables[0];
              this.SetState(true);
              this.MainInit();
            };
            this.gridControl1.Invoke(a);
        }
    
        2
  •  1
  •   Henk Holterman    14 年前

    将表作为数据源附加后,它属于GUI。假设您的用户在Calc线程运行时更改/删除了一行。各种各样的比赛条件都可能发生。