【问题标题】:Is there any way to handle an inaccessible exception?有没有办法处理无法访问的异​​常?
【发布时间】:2011-01-21 06:16:40
【问题描述】:

在 Silverlight 4 应用程序中,我在包含的控件 (DataGrid) 上调用函数,该函数有时会引发 MS.Internal.WrappedException 类型的虚假异常。由于这个异常没有意义,我需要吞下它。不幸的是,异常在 System.Windows.dll 中声明为 internal class WrappedException : Exception,所以我不能在 catch 块中命名它。

问题是,检测此异常并忽略它的最安全方法是什么?我想出的两个选项是:

  1. 查找原始异常:ex.InnerException is InvalidOperationException
  2. 查找名称:ex.GetType().FullName == "MS.Internal.WrappedException"

一种方式比另一种更好吗?还有其他我没有想到的选择吗?

这是显示不同选项的函数:

    private void SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var selectedAlarm = alarmList.SelectedItem as Alarm;
        if (selectedAlarm != null)
        {
            dataGrid.SelectedItem = selectedAlarm.Source;
            try
            {
                dataGrid.ScrollIntoView(dataGrid.SelectedItem, null);
            }
            // catch (MS.Internal.WrappedException ex) doesn't compile
            catch (Exception ex)
            {
                if (ex.InnerException is InvalidOperationException) // 1
                if (ex.GetType().FullName == "MS.Internal.WrappedException") // 2
                {
                    // ignore exception
                }
                else
                    throw;
            }
        }
    }

对于那些感兴趣的人,这里是 StackTrace:

在 MS.Internal.XcpImports.CheckHResult(UInt32 小时) 在 MS.Internal.XcpImports.UIElement_Measure(UIElement 元素,Size availableSize) 在 System.Windows.UIElement.Measure(可用大小) 在 System.Windows.Controls.DataGrid.InsertDisplayedElement(Int32 插槽,UIElement 元素,布尔 wasNewlyAdded,布尔 updateSlotInformation) 在 System.Windows.Controls.DataGrid.InsertDisplayedElement(Int32 插槽,布尔 updateSlotInformation) 在 System.Windows.Controls.DataGrid.GetExactSlotElementHeight(Int32 插槽) 在 System.Windows.Controls.DataGrid.ScrollSlotIntoView(Int32 插槽,布尔滚动水平) 在 System.Windows.Controls.DataGrid.ScrollSlotIntoView(Int32 columnIndex,Int32 插槽,布尔 forCurrentCellChange,布尔力水平滚动) 在 System.Windows.Controls.DataGrid.ScrollIntoView(对象项,DataGridColumn 列) 在 DtDemo.Home.alarmList_SelectionChanged(对象发送者,SelectionChangedEventArgs e)

这里是 InnerException.StackTrace:

在 System.Windows.Controls.DataGridRow.get_ActualDetailsVisibility() 在 System.Windows.Controls.DataGridRow.OnApplyTemplate() 在 System.Windows.FrameworkElement.OnApplyTemplate(IntPtr nativeTarget)

【问题讨论】:

    标签: c# silverlight exception


    【解决方案1】:

    这是故意的,所以你不要试图捕捉这个异常。这是一个严肃的问题,它不是没有意义的,不要忽略它。解决真正的问题。如果没有堆栈跟踪,我无法帮助您诊断原因。

    【讨论】:

    • 我非常同意;这是来自 DataGrid 的关键内部异常,它告诉您对 ScrollIntoView 的调用失败并且可能已将控件置于无效状态。如果不是严重异常,那么它就是控件中的严重错误(这种可能性较小。)
    • 一旦异常被忽略,应用程序工作正常,我无法想象如何调试问题,但我已经发布了异常的堆栈跟踪,以防有人可以提供帮助。
    • @Gabe,在调用 ScrollIntoView() 之前尝试调用 DataGrid.UpdateLayout()。我做了一些阅读,目前 DataGrid 中存在一些与虚拟化相关的已知错误,这些错误可能会导致 ScrollIntoView() 出现问题。
    • 好的,我同意,这闻起来像一个错误或他们只是没有指望的条件。没有什么比线程问题或严重的 Windows 错误更重要了。 WrappedException 的完美浪费;)
    • 我不得不争辩说,它应该从不有意公开内部异常类型。我认为任何公共接口抛出非公共异常类型都是一个错误。
    【解决方案2】:

    我更喜欢ex.InnerException is InvalidOperationException 的测试,并且还可能检查 InnerException 的一些属性。

    不过,这是一个主观判断。它以某种方式感觉不那么“hacky”,并且可能不太可能在未来的版本中中断。你认为微软更有可能更改其内部包装类的命名空间或类名,还是做一些类似直接抛出 InvalidOperationException 而不包装它的事情?

    当然,理想情况下,您可以首先阻止抛出异常。我相信你已经用尽了这条路线。

    【讨论】:

    • 我不确定要检查 InternalException 的哪些道具。消息是本地化的,所以没用。我当然不想依赖堆栈跟踪!
    【解决方案3】:

    没关系。我实际上应该阅读整篇文章。

    我会投票支持使用反射(选项 #2)。

    我认为这是应该向 Microsoft 报告的错误:程序集的公共接口不应向其使用者抛出内部或私有异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-04
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2016-07-04
      相关资源
      最近更新 更多