从线程中更新数据网格视图会导致错误 C# Winform
本文关键字:错误 Winform 视图 网格 线程 更新 数据 数据网 | 更新日期: 2023-09-27 18:34:19
我正在编写一个使用datagridview对象的C#wform。在程序的某个时刻,我需要从线程内更新所述数据网格视图。这会导致程序抛出一个未经处理的异常,指出对象引用未设置为对象的实例,并使 datagridview 变成带有红色 X 的白框的错误图像。
具体来说,在这种情况下,我试图做的是通过删除行并更新统计值并重新插入行来更新行中的值。
我在线程调用的单独函数中执行此操作,并且每次都会更新数据网格视图中的两行。
这是我的更新函数的代码:
private void updateStats(int binNumber)
{
binNumber *= 2;//has to multiply by 2 because every bin has two rows in this table
if (statsData.Rows.Count >= (binNumber + 1))
{
statsData.Rows.RemoveAt(binNumber);
//number does not change because the index was just decreased by one
statsData.Rows.RemoveAt(binNumber);//because every bin requires two rows
}
Bin bin = bins[binNumber / 2];
List<double> realETempData = new List<double>();
List<double> imagETempData = new List<double>();
List<double> realAlphaTempData = new List<double>();
List<double> imagAlphaTempData = new List<double>();
//updates average and std dev values
foreach (MinSearchData dataPoint in bin.binData)
{
realETempData.Add(dataPoint.RealE);
imagETempData.Add(dataPoint.ImagE);
realAlphaTempData.Add(dataPoint.RealAlpha);
imagAlphaTempData.Add(dataPoint.ImagAlpha);
}
bin.AverageRealE = realETempData.Average();
bin.AverageImagE = imagETempData.Average();
bin.StdDevRealE = calculateStandardDeviation(realETempData);
bin.StdDevImagE = calculateStandardDeviation(imagETempData);
bin.AverageRealAlpha = realAlphaTempData.Average();
bin.AverageImagAlpha = imagAlphaTempData.Average();
bin.StdDevRealAlpha = calculateStandardDeviation(realAlphaTempData);
bin.StdDevImagAlpha = calculateStandardDeviation(imagAlphaTempData);
realETempData.Clear();
imagETempData.Clear();
realAlphaTempData.Clear();
imagAlphaTempData.Clear();
DataRow myRow = statsData.NewRow();
myRow[0] = bin.BinName;
myRow[1] = "Real";
myRow[2] = bin.AverageRealAlpha;
myRow[3] = bin.StdDevRealAlpha;
myRow[4] = bin.AverageRealE;
myRow[5] = bin.StdDevRealE;
statsData.Rows.InsertAt(myRow, binNumber);
DataRow myRow2 = statsData.NewRow();
myRow2[0] = "";
myRow2[1] = "Imaginary";
myRow2[2] = bin.AverageImagAlpha;
myRow2[3] = bin.StdDevImagAlpha;
myRow2[4] = bin.AverageImagE;
myRow2[5] = bin.StdDevImagE;
statsData.Rows.InsertAt(myRow2, binNumber + 1);
}
更奇怪的是,我似乎无法捕获异常,并且它发生不一致,因为有时它在第一次尝试更新时失败,而其他时候它在第一次尝试时失败。
任何帮助将不胜感激,
谢谢
-杰克
这可能是
由于race
问题造成的。换句话说,一个线程(可能是主线程(尝试根据其当前行列表绘制网格,而另一个线程推断和操作它。此外,我想您已经关闭了CheckForIllegalCrossThreadCalls
,以便能够直接通过线程操作网格。如果是,这是问题的主要原因。无论如何,可能的解决方案是使用 BeginInvoke
间接使用控件:
private void updateStats(int binNumber)
{
datagridview1.BeginInvoke(new MethodInvoker(() =>
{
binNumber *= 2;//has to multiply by 2 because every bin has two rows in this table
if (statsData.Rows.Count >= (binNumber + 1))
....
....
....
myRow2[5] = bin.StdDevImagE;
statsData.Rows.InsertAt(myRow2, binNumber + 1);
}
}
编辑:
我以为statsData
是一个DataGridView
.根据OP的评论,这是一个DataTable
。因此,我定制了答案以反映这一事实。