使用 Backgroundworkers 时出错

Getting errors while using Backgroundworkers

我正在制作动态仪表板,这就是为什么所有数据网格和数据图表都应该使用后台工作者。因为有时从数据库中获取数据需要 5-10 秒,同时如果我不使用后台工作程序,应用程序会冻结。所以使用后台工作者对我来说是必须的。

如果我不使用后台工作人员,我不会收到任何错误。 但是,当我在不同时间(有时在 5 分钟内,有时在 1 小时后)使用后台工作人员时,出现以下错误;

1-) System.ArgumentException: An item with the same key has already been added
2-) object reference not set to an instance of an object

我不知道这是什么原因。正如我所说,如果我不使用后台工作人员,一切正常。

这是图表上的示例代码和后台工作人员的用法。

public void getTopSQL()

{
    dtTopSQL.Clear();
    odaTopSQL = new OracleDataAdapter(getTopSQLDetails, oradb);
    odaTopSQL.Fill(dtTopSQL);
    dtCurTopSQL.Merge(dtTopSQL); // Get current values from datatable dtTopSQL and add rows to general datatable 'dtCurTopSQL'

        if (dtCurTopSQL.AsEnumerable().Any() == true) // check for if datatable is not empty
        {
            maxDate = dtCurTopSQL.AsEnumerable().Max(z => z.Field<DateTime>("SAMPLE_TIME"));
            minDate = maxDate.AddSeconds(-90);
        }



        var isFull = dtCurTopSQL.AsEnumerable()  // check for if datatable is not empty
          .Where(l => l.Field<DateTime>("SAMPLE_TIME") >= minDate && l.Field<DateTime>("SAMPLE_TIME") <= maxDate).Any();



        if (isFull == true) // Here the magic happens.
        {
           var dt1 = dtCurTopSQL.AsEnumerable()
          .Where(l => l.Field<DateTime>("SAMPLE_TIME") >= minDate && l.Field<DateTime>("SAMPLE_TIME") <= maxDate)
          .GroupBy(h => h.Field<string>("SQL_ID"))
          .Select(g =>
          {
              DataRow row2 = dtCurTopSQL.NewRow();
              row2["SQL_ID"] = g.Key;
              row2["CountAll"] = g.Sum(h => h.Field<int>("CountAll"));
              row2["CPU"] = g.Sum(h => h.Field<int>("CPU"));
              row2["Scheduler"] = g.Sum(h => h.Field<int>("Scheduler"));
              row2["Activity"] = 0;
              return row2;
          }).CopyToDataTable();   
            ugTopSQL.DataSource = dt1;
        }

        else
        {
            ugTopSQL.DataSource = null;
        }                
}

private void bgwTA_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
 {
     getTA();
 }

try
{
    if (!bgwTA.IsBusy)
    {
        bgwTA.RunWorkerAsync();
    }
}
catch
{
    MessageBox.Show("Error : Wait Event Reader!");
}

这是错误的堆栈跟踪;

System.ArgumentException: An item with the same key has already been added.
   konum: System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   konum: System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   konum: Infragistics.Win.UltraWinGrid.UltraGridRow.get_ScrollCountInternal()
   konum: Infragistics.Win.UltraWinGrid.UltraGridRow.Infragistics.Shared.ISparseArrayMultiItem.get_ScrollCount()
   konum: Infragistics.Shared.SparseArray.EnsureScrollCountCalculatedHelper(NodeExtended n)
   konum: Infragistics.Shared.SparseArray.EnsureScrollCountCalculated()
   konum: Infragistics.Shared.SparseArray.GetVisibleCount()
   konum: Infragistics.Win.UltraWinGrid.RowsCollection.GetSpecialRowsHelper(List`1 list, Boolean top, UltraGridRow[] rowsToRecycle)
   konum: Infragistics.Win.UltraWinGrid.RowsCollection.CalcSpecialAndFixedRowsHelper(List`1& outSpecialRows, List`1& outFixedRows, Boolean top, UltraGridRow[] rowsToRecycle)
   konum: Infragistics.Win.UltraWinGrid.RowsCollection.EnsureSpecialAndFixedRowsCacheCalculated()
   konum: Infragistics.Win.UltraWinGrid.RowsCollection.GetFixedRows(Boolean top)
   konum: Infragistics.Win.UltraWinGrid.RowsCollection.HasFixedRows(Boolean top)
   konum: Infragistics.Win.UltraWinGrid.ViewStyleBase.get_Using_CreateRowsList_FixedRowsFeature()
   konum: Infragistics.Win.UltraWinGrid.ViewStyleBase.RecreateRowList(RowScrollRegion rsr, Boolean syncWithCalcManager)
   konum: Infragistics.Win.UltraWinGrid.RowScrollRegion.GetMaxScrollPosition(Boolean scrollToFill, Boolean ignoreScrollBoundsResolved)
   konum: Infragistics.Win.UltraWinGrid.RowScrollRegion.EnsureScrollRegionFilled(Boolean calledFromRegenerateVisibleRows)
   konum: Infragistics.Win.UltraWinGrid.RowScrollRegion.RegenerateVisibleRows(Boolean resetScrollInfo)
   konum: Infragistics.Win.UltraWinGrid.RowScrollRegion.RegenerateVisibleRows()
   konum: Infragistics.Win.UltraWinGrid.DataAreaUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UltraWinGrid.UltraGridUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics, Nullable`1 zoomFactor)
   konum: Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize, Boolean preventAlphaBlendGraphics)
   konum: Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode)
   konum: Infragistics.Win.UltraWinGrid.UltraGridUIElement.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode)
   konum: Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe)
   konum: Infragistics.Win.UltraWinGrid.UltraGrid.OnPaint(PaintEventArgs pe)
   konum: System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   konum: System.Windows.Forms.Control.WmPaint(Message& m)
   konum: System.Windows.Forms.Control.WndProc(Message& m)
   konum: System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   konum: System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   konum: System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

第二个;

System.NullReferenceException: object reference not set to an instance of an object.
   konum: Infragistics.Win.UltraWinGrid.UltraGridRow.get_BaseHeight()
   konum: Infragistics.Win.UltraWinGrid.VisibleRow.GetDimensions(ColScrollRegion csr, VisibleRowDimensions dimensions, DimOriginBase originBase)
   konum: Infragistics.Win.UltraWinGrid.RowColRegionIntersectionUIElement.PositionChildElements()
   konum: Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UltraWinGrid.RowColRegionIntersectionUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UltraWinGrid.DataAreaUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UltraWinGrid.UltraGridUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive)
   konum: Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics, Nullable`1 zoomFactor)
   konum: Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize, Boolean preventAlphaBlendGraphics)
   konum: Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode)
   konum: Infragistics.Win.UltraWinGrid.UltraGridUIElement.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode)
   konum: Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe)
   konum: Infragistics.Win.UltraWinGrid.UltraGrid.OnPaint(PaintEventArgs pe)
   konum: System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   konum: System.Windows.Forms.Control.WmPaint(Message& m)
   konum: System.Windows.Forms.Control.WndProc(Message& m)
   konum: System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   konum: System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   konum: System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

您遇到了一个问题,您似乎试图插入数据表中已存在的键,因此这是不允许的。但是我看不到你的数据所以很难看到示例问题。

但是您确实遇到了另一个问题,它可能不会给您带来问题,但它会。那就是你不能从后台工作者调用 UI 元素(例如消息框)。

UI 元素始终在主线程上,而后台工作者可以在任何线程上,因此您首先需要检查然后调用委托来调用。

但更好的方法是实际使用

的后台工作者事件
ProgressChanged
RunWorkerCompleted

这些在启动后台工作程序的同一线程上执行。因此,如果您从表单调用它,那么它已经是您的 UI 线程。所以这让生活更轻松。

您的代码太长,无法在此处重复所有内容,但我会为您提供一个关于所需内容的大纲。

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += bgwTA_DoWork;
worker.RunWorkerCompleted += bgwTA_RunWorkerCompleted;
worker.RunWorkerAsync();

private void bgwTA_DoWork(object sender, DoWorkEventArgs e)
{
    dtTopSQL.Clear();
    odaTopSQL = new OracleDataAdapter(getTopSQLDetails, oradb);
    odaTopSQL.Fill(dtTopSQL);
    //etc

    e.Result = dt1;
}

private void bgwTA_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   {
    if (e.Cancelled)
    {
        //Process was cancelled, need to clean up here
    }
    else if (e.Error != null)
    {
        //Here was an error running the process. or the thread aborted.  
        //Need to raise errors and clean up here
        //If your process threw an exception, then it will be here                
    }
    else
    {
        //Everything worked OK, now we can update our UI elements
        //The Worker Completed thread will come back to the thread which called it.  Which, means if called from you main UI thread that you don't have to use invoke

        ugTopSQL.DataSource = (DataTable)e.Result;
    }
}