Я сталкиваюсь со сложной ошибкой, связанной с инструментом Dundas Charting for Winforms, который используется в MS Visual Studio 2008 C #.
Следующая ошибка возникает при возникновении события GUI для объекта Chart во время его аннулирования. Когда происходит ошибка, диаграмма dundas показывает большую X-метку.
...
************** 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)
Сценарий таков:
- У меня есть сетка, в которой есть список объектов, которые ссылаются на наносимый ряд.
- График обновляется каждую 1 секунду, используя chart.Invoke (AddData)
Это событие, которое вызывает сбой:
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;
}
}
}
}
Рисование выполняется следующим образом
Фоновая нить захватывает
Это событие поднимает
OnDataAvailable каждую секунду
Вот обработчик
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);
}
}
Интересной особенностью этой ошибки является то, что она встречается не на всех машинах. Я заметил, что это происходит на машинах с высокими техническими характеристиками, таких как наш 8-ядерный процессор DELL и новый четырехъядерный ноутбук, который мы получили здесь. Это вызвало подозрение на проблему с многопоточностью; тем не менее, с потоками все в порядке, поскольку доступ к объекту диаграммы осуществляется из того же основного потока.
Пожалуйста, помогите мне с этим
UPDATE
присвоение с помощью установщика, которое происходит в функции dataGridView1_CellEndEdit
MUChart.Series [boundData.SeriesName] .ChartArea
= boundData.ChartArea.ToString (); вызывает диаграмму. внутренне
в то время как вызываемая функция AddData, которая обновляет эту диаграмму, вызывает ее явно. Я прочитал в библиотеке MSDN, что «control.invalidate» не вызывает синхронную рисование, если после него не вызывается control.update. Я почти уверен, что конфликт происходит после аннулирования, даже если все происходит в одном потоке, поскольку перерисовка происходит асинхронно.
Я понял, что происходит таким образом, но я не знаю, как этого избежать. control.update не приносит мне пользы.
ChangeTheChartConfigurations ();
DrawTheChanges () ---- >>>> это работает асинхронно
UpdateDataPoints ()
DrawTheChanges () ---- >>> это работает, пока первое изменение еще не произошло. Например, серия могла быть перемещена в область разностной диаграммы, и Dundas.Charting.WinControl.AxisScale.a (Double) (последняя функция в трассировке стека) вызывается в уже скрытой области диаграммы.
это просто мысль
UPDATE
Я зарегистрировал идентификатор потока как из обработчика событий, так и из функции AddNewPoint, и он совпадал с основным потоком