6 Stimmen

Red X GUI stürzt ab! Ich habe fast aufgegeben, das Problem zu lösen!

Ich stehe vor einem komplexen Fehler mit dem Dundas Charting for Winforms-Tool, das mit MS Visual Studio 2008 C# verwendet wird.

Der folgende Fehler tritt auf, wenn ein GUI-Ereignis für das Chart-Objekt ausgelöst wird, während es ungültig gemacht wird. Wenn der Fehler auftritt, zeigt das Dundas-Diagramm ein großes X an. ...

************** Exception Text **************

System.ArgumentOutOfRangeException: Axis Object - The Interval can not be zero
Parameter name: diff
   at Dundas.Charting.WinControl.AxisScale.a(Double )
   at Dundas.Charting.WinControl.Axis.a(Double , Double , AxisScaleSegment , DateTimeIntervalType& )
   at Dundas.Charting.WinControl.Axis.a(ChartGraphics , Boolean , AxisScaleSegment , Boolean )
   at Dundas.Charting.WinControl.Axis.b(ChartGraphics , Boolean , Boolean )
   at Dundas.Charting.WinControl.Axis.Resize(ChartGraphics chartGraph, ElementPosition chartAreaPosition, RectangleF plotArea, Single axesNumber, Boolean autoPlotPosition)
   at Dundas.Charting.WinControl.ChartArea.a(ChartGraphics )
   at Dundas.Charting.WinControl.ChartPicture.Resize(ChartGraphics chartGraph, Boolean calcAreaPositionOnly)
   at Dundas.Charting.WinControl.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly, RenderingType renderingType, XmlTextWriter svgTextWriter, Stream flashStream, String documentTitle, Boolean resizable, Boolean preserveAspectRatio)
   at Dundas.Charting.WinControl.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
   at Dundas.Charting.WinControl.Chart.OnPaint(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Das Szenario sieht folgendermaßen aus:

  • Ich habe eine Gitteransicht, die eine Liste von Objekten enthält, die auf die darzustellende Serie verweisen.
  • Die Darstellung wird alle 1 Sekunde mit chart.Invoke(AddData) aktualisiert.

Dies ist das Ereignis, das den Absturz verursacht:

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
    {
        AppDataSeries boundData =
dataGridView1[e.ColumnIndex, e.RowIndex].OwningRow.DataBoundItem as AppDataSeries;

        if (boundData.Tag != null)
        // Tag is of Type Dundas.Charting.WinControl.Series
        {
            switch (e.ColumnIndex)
            {
                case 1:
                    MUChart.Series[boundData.SeriesName].ChartArea = 
                          boundData.ChartArea.ToString();
                    // when you change the chart area of a series it
                    // crashes the chart control
                    // also when you enable or disable a series using
                    // series1.Enabled = true,
                    // it could crash the chart control
                    MUChart.ChartAreas[boundData.ChartArea].Visible = true;
                    break;

            }
        }
    }
}

Die Zeichnung wird auf folgende Weise angefertigt

Ein Hintergrund-Thread erfasst

Sie hebt das Ereignis

OnDataAvailable jede Sekunde

Hier ist der Handler

void serviceWrapperInstance_DataAvailable(object sender, DataAvailableEventArgs e)
{
    if (e.ViewId == currentViewId)
    {
        if (MUChart.InvokeRequired)
        {
            MUChart.Invoke((MethodInvoker)AddData);
        }

        else
        {
            AddData();
        }
    }
}
public void AddData()
{
    if (MUChart.Series.Count > 0)
    {
        for (int i = 0; i < currentViewSeries.Count; i++)
        {
            AddNewPoint(currentViewSeries[i].XValue, MUChart.Series[i],
currentViewSeries[i].YValue * ((currentViewSeries[i].IsInverse) ? -1 : 1),
currentViewSeries[i].ChartColor);

            dataSaver[MUChart.Series[i].Name].Add(new DataPoint(currentViewSeries[i].XValue,
(double)currentViewSeries[i].YValue));

        }
    }
}
public void AddNewPoint(double xValue, Series ptSeries, double yValue,
Color pointColor)
{
    try
    {
        ptSeries.Points.AddXY(xValue, yValue);
        if (draggedDroppedSeriesMapper.ContainsKey(ptSeries))
            foreach (Series item in draggedDroppedSeriesMapper[ptSeries].DraggedDroppedSeriesVersions)
                item.Points.AddXY(xValue, yValue);
        MUChart.Invalidate();
        // if I remove the previous line the plot doesn’t crash, but doesn’t update !!
    }
    catch (Exception ex)
    {
        Logger.Log(TraceLevel.Error, "AddNewPoint()", ex);
    }
}

Das Interessante an diesem Fehler ist, dass er nicht auf allen Rechnern auftritt. Mir ist aufgefallen, dass er auf Hochleistungsrechnern wie unserem DELL-Rechner mit 8-Kern-CPU und einem neuen Quad-Core-Laptop auftritt, den wir hier gekauft haben. Dies ließ den Verdacht aufkommen, dass es sich um ein Threading-Problem handelt; allerdings scheint das Threading in Ordnung zu sein, da auf das Diagrammobjekt von demselben Haupt-Thread aus zugegriffen wird.

Bitte helfen Sie mir dabei

UPDATE die Zuordnung über den Setter, der in der Funktion dataGridView1_CellEndEdit stattfindet MUChart.Series[boundData.SeriesName].ChartArea = boundData.ChartArea.ToString(); ruft chart.invalidate intern auf, während die aufgerufene Funktion "AddData", die das Diagramm aktualisiert, diese Funktion explizit aufruft. Ich habe in der MSDN-Bibliothek gelesen, dass "control.invalidate" keine synchrone Zeichnung erzwingt, wenn control.update nicht danach aufgerufen wird. Ich bin mir fast sicher, dass der Konflikt bei der Invalidierung auftritt, obwohl alles auf demselben Thread abläuft, da das Neuzeichnen asynchron erfolgt. Ich habe verstanden, was auf diese Weise geschieht, aber ich weiß nicht, wie ich es vermeiden kann. control.update tut mir nicht gut.

ChangeTheChartConfigurations(); DrawTheChanges() ---- >>>> dies funktioniert asynchron UpdateDataPoints() DrawTheChanges() ---- >>> dies funktioniert, während die erste Änderung noch nicht stattgefunden hat. Zum Beispiel könnte die Serie in einen anderen Diagrammbereich verschoben worden sein und Dundas.Charting.WinControl.AxisScale.a(Double ) (die letzte Funktion im Stacktrace) wird auf einem bereits ausgeblendeten Diagrammbereich aufgerufen das ist nur ein Gedanke

UPDATE

Ich habe die Thread-ID sowohl vom Event-Handler als auch von der AddNewPoint-Funktion protokolliert, und sie war dieselbe wie die des Hauptthreads

0 Stimmen

Bitte bereinigen Sie die Formatierung des Codes. In seinem jetzigen Zustand ist er SEHR schwer zu lesen.

0 Stimmen

Ich habe es bearbeitet, besser geht es nicht

0 Stimmen

Nein, ist es nicht. Entfernen Sie Leerzeilen und entfernen Sie die Einrückung.

0voto

Lakewind Punkte 29

Ich traf den gleichen Fehler und fand den Grund ist ich AxisIntervalMode als VaiableCount festgelegt, auch wenn es keine Daten gibt. Also ändere ich den AxisIntervalMode dynamisch, je nachdem, ob die Serie Daten hat. Ich hoffe, dies kann jemandem helfen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X