填写dataGridView谢谢backGroundWorker

我有这段代码:

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { remplirDataGrid(); } private void frmChercherActesLoad(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } private void remplirDataGrid() { dataGridView1.DataSource = ActeServices.getAllActes(0, 40); dataGridView1.Columns[0].Visible = false; dataGridView1.Columns[1].HeaderText = "Code acte"; dataGridView1.Columns[2].HeaderText = "Désignation"; dataGridView1.Columns[3].HeaderText = "Pris en charge"; dataGridView1.Columns[4].HeaderText = "Id article"; dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); } 

这是方法getAllActe

 public static IEnumerable getAllActes(int skipCount, int takeCount) { var myTableAdapter = new SmartDocDALServices.SmartDocDataSetTableAdapters.actesTableAdapter(); myTableAdapter.Fill(myDataSet.actes); var myResult = from q in myDataSet.actes.AsEnumerable() select new Acte { code = q.code, designation = q.designation, priseEnCharge = q.prise_en_charge, idArticle = q.id_article, }; if (skipCount != -1) myResult.Skip(skipCount); if (takeCount != -1) myResult.Take(takeCount); IEnumerable myResultRet = myResult.ToList(); return myResultRet; 

我喜欢做的是在运行应用程序后使用后台工作程序填充我的datagridview我收到此错误:

线程间操作无效:控制’dataGridView1已成为从创建它以外的线程进行访问的主题。


我试试这个

  private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { IEnumerable result = ActeServices.getAllActes(0, 40); backgroundWorker1.ReportProgress(0, result); } void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { dataGridView1.DataSource = (IEnumerable)e.UserState; dataGridView1.Columns[0].Visible = false; dataGridView1.Columns[1].HeaderText = "Code acte"; *** 

但没有及时获得? 我希望当BGW加载数据foreash数据加载时,datagrid更新它将它添加到DGV

您无法从BackgroundWorker线程更新UI。

您需要向UI发送一个事件,然后执行以下操作:

 private void EventHandler(object sender, YourEventArgs e) { if (this.dataGridView1.InvokeRequired) { this.dataGridView1.Invoke((MethodInvoker)delegate { this.AddToGrid(e.YourData); }); } else { this.AddToGrid(e.YourData); } } 

DataGridView不是线程安全的。 但是,如果数据已经可用,则设置DataSource应该足够快。

我建议:

  1. 仅使用BackgroundWorker在另一个线程中加载数据

  2. 在RunWorkerCompleted事件中设置DataSource和datagridview的其他修改(您可以通过设置将结果从DoWork方法传递给Completed事件

    e.Result = ActeServices.getAllActes(0,40);

  3. 可选:将dataGridView1.AutoGenerateColumns设置为false,并在Windows窗体设计器或代码中手动添加列以避免闪烁。

这是因为GUI内容无法从GUI线程以外的其他线程进行修改。 要解决此问题,您需要使用Dispatcher调用GUI线程上的更改。

应该事先设置DataGrid,因此您在异步操作中所做的就是填充数据。

 var data = ActeServices.getAllActes(0, 40); Dispatcher.BeginInvoke( new Action( () => { dataGridView1.DataSource = data; })) 

BackgroundWorker类旨在在后台线程上运行长期操作。 由于您只能从创建它们的线程访问UI组件,因此您可以使用BackgroundWorker类的RunWorkerCompleted事件在DoWork处理程序完成后更新UI。 此外,您可以使用BackgroundWorker类的ProgressChanged事件安全地更新进度UI。