当我明确要求控件重绘时,为什么没有捕获绘制异常?

发布于 2024-11-16 02:29:56 字数 2732 浏览 0 评论 0原文

我有一个 GUI 应用程序,它使用 Windows::Forms::DataVisualization::Charting::Chart 显示数据,大多数情况下工作正常。只是偶尔我们会得到一些图表控件不喜欢的虚假数据,从而引发异常。为了尝试捕获导致这些问题的原因,我将重新绘制请求包装在 try/catch 中:

try
{
    m_chart->Invalidate();
    m_chart->Update();
}
catch(System::Exception^ e)
{
    // If something goes wrong during the drawing, we probably want to try 
    // and record some more information then re-throw it so we can capture 
    // it properly.
    String^ detailString = String::Format("Exception caught while trying to draw raw data. {0}", "Add more debug info here");
    throw gcnew System::Exception(detailString, e);
}

...不过出于某种原因,异常不会在那里抛出(我有一个断点和一些日志记录永远不会被击中) - 它发生在其他某个时刻:

Exception:
    Value was either too large or too small for a Decimal.
Exception type:
    System.OverflowException
Source:
    mscorlib
Stack trace:
   at System.Decimal..ctor(Double value)
   at System.Windows.Forms.DataVisualization.Charting.Axis.RoundedValues(Double inter, Boolean shouldStartFromZero, Boolean autoMax, Boolean autoMin, Double& min, Double& max)
   at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateNumberAxis(Double& minimumValue, Double& maximumValue, Boolean shouldStartFromZero, Int32 preferredNumberOfIntervals, Boolean autoMaximum, Boolean autoMinimum)
   at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis(Double& minimumValue, Double& maximumValue, Boolean autoMaximum, Boolean autoMinimum)
   at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis()
   at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetDefaultAxesValues()
   at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetData(Boolean initializeAxes, Boolean checkIndexedAligned)
   at System.Windows.Forms.DataVisualization.Charting.ChartArea.ReCalcInternal()
   at System.Windows.Forms.DataVisualization.Charting.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
   at System.Windows.Forms.DataVisualization.Charting.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.OnMessage(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)
Installed .net Versions:
    v2.0.50727.5420
    v3.0.30729.5420
    v3.5.30729.5420
    v4.0.30319

我在这里错过了什么吗?无效/更新是否不会触发与 Windows 消息泵的其他部分相同的重新绘制?

I have a GUI app which displays data using a Windows::Forms::DataVisualization::Charting::Chart which works fine most of the time. Just occasionally we get some spurious data which the chart control doesn't like which throws an exception. To try and capture what it is that causes these problems I've wrapped the re-draw request in a try/catch:

try
{
    m_chart->Invalidate();
    m_chart->Update();
}
catch(System::Exception^ e)
{
    // If something goes wrong during the drawing, we probably want to try 
    // and record some more information then re-throw it so we can capture 
    // it properly.
    String^ detailString = String::Format("Exception caught while trying to draw raw data. {0}", "Add more debug info here");
    throw gcnew System::Exception(detailString, e);
}

...for some reason though, the exception isn't thrown there (I have a breakpoint and some logging which never get hit) - it happens at some other point:

Exception:
    Value was either too large or too small for a Decimal.
Exception type:
    System.OverflowException
Source:
    mscorlib
Stack trace:
   at System.Decimal..ctor(Double value)
   at System.Windows.Forms.DataVisualization.Charting.Axis.RoundedValues(Double inter, Boolean shouldStartFromZero, Boolean autoMax, Boolean autoMin, Double& min, Double& max)
   at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateNumberAxis(Double& minimumValue, Double& maximumValue, Boolean shouldStartFromZero, Int32 preferredNumberOfIntervals, Boolean autoMaximum, Boolean autoMinimum)
   at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis(Double& minimumValue, Double& maximumValue, Boolean autoMaximum, Boolean autoMinimum)
   at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis()
   at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetDefaultAxesValues()
   at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetData(Boolean initializeAxes, Boolean checkIndexedAligned)
   at System.Windows.Forms.DataVisualization.Charting.ChartArea.ReCalcInternal()
   at System.Windows.Forms.DataVisualization.Charting.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
   at System.Windows.Forms.DataVisualization.Charting.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.OnMessage(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)
Installed .net Versions:
    v2.0.50727.5420
    v3.0.30729.5420
    v3.5.30729.5420
    v4.0.30319

Have I missed something here? Does invalidate / update not trigger the same re-draw that some other part of the windows message pump does?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别闹i 2024-11-23 02:29:56

大多数 UI 框架都遵循这种模式。 Invalidate等只需更新窗口状态中的标志,以便稍后重新绘制。

如果您无法捕获绘制代码中的错误,则必须处理 ThreadException。捕获绘制(或数据绑定)代码中的错误是首选解决方案,但如果您只是临时添加一个处理程序来查看数据是什么,ThreadException 应该可以正常工作。

Most UI frameworks follow this kind of pattern. Invalidate, etc. just update flags in the window state so that it will be repainted later.

If you can't catch the error in the painting code, you'll have to handle ThreadException. Catching the error in the painting (or data binding) code is the preferred solution, but if you're just temporarly adding a handler to see what the data is, ThreadException should work fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文