簡體   English   中英

從線程內更新datagridview會導致錯誤C#Winform

[英]updating datagridview from within a thread causes error c# winform

我正在編寫一個使用datagridview對象的C#winform。 在程序的某個點上,我需要從線程內更新所述datagridview。 這導致程序拋出未處理的異常,該異常表示對象引用未設置為對象的實例,並使datagridview變成帶有紅色X的白色框的錯誤圖像。

具體來說,在這種情況下,我要嘗試的是通過刪除行並更新統計值並重新插入行來更新行中的值。

我在線程調用的單獨函數中執行此操作,並且每次都會更新datagridview中的兩行。

這是我的更新功能的代碼:

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);
   }
}

編輯:

我以為statsDataDataGridView 根據OP的注釋,它是一個DataTable 因此,我量身定制了答案以反映這一事實。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM