Windows 8.1 XAML 尽管有错误处理,应用程序仍然崩溃

Windows 8.1 XAML application crashes despite error handling

这是我在使用 Windows 8.1 XAML 应用程序时遇到的一个奇怪问题。

尽管我实施了异常处理,但 DevExpress 控件中的错误导致整个应用程序崩溃。 DevExpress 开发人员已经复制了这个特定的错误并正在研究解决方案 - 这个问题是关于尽管有错误处理但崩溃的问题,而不是关于 DevExpress 错误。

这次崩溃的独特之处在于它在 App.g.i.cs 中自动生成的代码中的这一行中断(与在其他地方抛出的其他异常相反):

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
            UnhandledException += (sender, e) =>
            {
                if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
            };
#endif

这似乎是在 XAML 相关机制中发生某种异常/崩溃时触发的(但这只是我的一个疯狂猜测)...我不认为上面的代码是造成 "crash to desktop" 效果的原因,但它似乎确实是一种症状。

我自己的错误处理代码(在App.xaml.cs):

public App()
{
  //...
  this.UnhandledException += App_UnhandledException;
  //...
}

private async void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    var ex = e.Exception;
    e.Handled = true;
    Logger.LoggingError(ex);
        await Controls.MessageDialog.Show(ex.Message, Controls.MessageDialog.DialogType.Error, Controls.MessageDialog.DialogButtons.Retry, ElementTheme.Light);
    var frame = Window.Current.Content as Frame;
    frame.Navigate(typeof(Views.SplashLoading));
}

错误处理尝试:

  1. 记录错误
  2. 显示错误
  3. 返回开始视图

同样 - 这通常适用于所有其他目的。但是,如果 App.g.i.cs 中的断点被触发(或将被触发,如果应用程序在客户端计算机上发布),那么我的错误处理将完全失败。

请注意,这不是 DevExpress 控件独有的。只是 DevExpress 控件以可以复制的方式导致此行为。同样 - 如果异常会导致 App.g.i.cs 中的代码被触发,那么似乎没有保存应用程序。

一旦这个不幸的事件发生,我该怎么做才能确保应用程序继续运行并且不会崩溃到桌面?

编辑:

供参考,这是使用 DevExpress 控件时出现的错误消息:

System.ArgumentException: The parameter is incorrect.

The value cannot be infinite or Not a Number (NaN).
   at Windows.UI.Xaml.Controls.ScrollViewer.ChangeView(Nullable`1 horizontalOffset, Nullable`1 verticalOffset, Nullable`1 zoomFactor, Boolean disableAnimation)
   at DevExpress.Core.Native.DXVirtualizingPanel.ScrollElementIntoView(Double elementOffset, Double rowHeight)
   at DevExpress.Core.Native.DXVirtualizingPanel.ScrollIntoView(Int32 visibleIndex)
   at DevExpress.UI.Xaml.Grid.DataControlBas

不幸的是,这是完整的消息 - 似乎缺少完整的堆栈跟踪。

显然设置 e.Handled = true; 保证应用程序不会崩溃(如 on MSDN 所述):

The Windows Runtime considers exceptions encountered during certain operations as nonrecoverable, because the Windows Runtime itself will be in an inconsistent state following these exceptions. For such exceptions, even if the UnhandledException event handler sets Handled to true, the app will still be terminated.

但是,为什么 DevExpress 的控件会导致这种无效状态对我来说是个谜......但至少它解决了为什么尽管事件正在处理但应用程序关闭的问题。

特别感谢 DevExpress 支持团队的人员,他们帮助解决了这个问题。