控制'dgDisplay'从除了使用Parallel.for创建的线程以外的线程访问

时间:2012-07-21 11:51:06

标签: c#

尝试使用Parallel.For

时出错
for (int i = 0; i <= count; i++)
{
  DataGridViewTextBoxColumn columnDataGridTextBox = new DataGridViewTextBoxColumn();
  columnDataGridTextBox.Name = fileDataField[i];
  columnDataGridTextBox.HeaderText = fileDataField[i];
  columnDataGridTextBox.Width = 120;
  dgDisplay.Columns.Add(columnDataGridTextBox);
}

我的代码与paraller.for

Parallel.For(0, count, i =>
{
  DataGridViewTextBoxColumn columnDataGridTextBox = new DataGridViewTextBoxColumn();
  columnDataGridTextBox.Name = fileDataField[i];
  columnDataGridTextBox.HeaderText = fileDataField[i];
  columnDataGridTextBox.Width = 120;
  dgDisplay.Columns.Add(columnDataGridTextBox); <<< this error add colums
});

1 个答案:

答案 0 :(得分:2)

控件只能在创建它们的线程中访问(并且只有一个UI线程)。如果您的调用来自另一个线程(由于您位于Parallel.For中,它会执行此操作),您必须使用Invoke方法和实际方法的委托。要测试您是否处于“错误”线程,可以使用InvokeRequired属性。

if (dgDisplay.InvokeRequired)
{
    dgDisplay.Invoke(addColumnDelegate, columnDataGridTextBox);
}
else
{
    dgDisplay.Columns.Add(columnDataGridTextBox);
}

当您从表单的事件处理程序中调用此代码时,它将阻塞,因为Invoke方法将同步执行。您必须使用BeginInvoke而不是Invoke来异步执行它。

除此之外,我不会在这里使用Parallel.For有两个原因:

  1. Parallel.For中,您无法预测元素的计算顺序。
  2. 由于所有调用都将在同一个线程中结束,因此并行执行不会带来任何好处。
  3. 如果列顺序无关紧要,并且您认为应该并行执行列的创建,我建议在DataGridViewColumn中构建一个Parallel.For对象数组,然后将它们分配给使用dgDisplay.Columns.AddRange(columns)进行控制。