使用Backgroundworkers时出错

时间:2017-06-23 04:37:02

标签: c# .net backgroundworker

我正在制作动态仪表板,这就是为什么所有数据网格和数据广告应该使用后台工作程序的原因。因为有时从数据库获取数据需要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

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

以下是图表上的示例代码和backgroundworkers的用法。

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)

1 个答案:

答案 0 :(得分:0)

您遇到的问题似乎是尝试插入已存在于数据表中的密钥,因此不允许这样做。但我无法看到您的数据,因此很难看到示例问题。

但是你有另一个问题,这可能不会导致你出现问题,但它会。也就是说,您无法从后台工作程序调用UI元素(例如消息框)。

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

但更好的方法是实际使用

的后台工作人员事件
ProgressChanged
RunWorkerCompleted

这些是在启动backgroundworker的同一个线程上执行的。因此,如果您从表单中调用它,那么它将已经是您的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;
    }
}