在发布模式下发生的UWP未处理异常

3
我已经苦恼了一个星期,因为我的发布的UWP应用程序中有一个bug,只在部署到手机(ARM目标)上的发布模式下才会表现出来。当从一个特定页面导航到另一个页面时,它会随机崩溃应用程序。即使这两个特定页面的结构与项目中的许多其他页面完全相同,也只影响这两个页面(使用OnNavigatedTo和OnLoaded来呈现内容并填充ViewModel等)。
我唯一拥有的线索(因为我无法获得完整的堆栈跟踪)是这个错误消息,我只能通过反复试错来很困难地获得:

[Exception](http://i.imgur.com/9Mpejje.jpg)

看起来这个问题很普遍,我试了几种方法:
  • 确保我的IValueConverters永远不会返回null或意外的值。
  • 确保没有变量未初始化。
  • 确保在访问任何组件之前完全加载UI。
  • 确保没有在Dispatcher线程之外进行UI操作。
  • 更新我的项目库(Newtonsoft JSON和winfbsdk,尽管后者在两个视图中都没有使用)。
经过大量阅读后,我尝试在项目设置中调整编译选项,并发现问题出在同时激活.NET本地工具链编译和代码优化复选框。我成功地在这些选项激活的情况下在Debug模式下重现了崩溃(基本上是玩应用程序,直到随机出现错误),但由于恰好激活了这些设置,我没有堆栈跟踪。调试器只是在Unhandled XAML异常行上中断,甚至方法的发送方和e参数“目前无法访问”。
另一方面,我有一些电话上的 minidump,无法在 Visual Studio 2015 上进行调试。即使我已经在配置中选中了 Microsoft 符号服务器,它也无法找到 kenelbase.pdb 符号。
即使我选择了 .NET native 编译选项(似乎需要两个),我也无法将应用上传到商店(否则,在验证期间网站会出现错误),因此我的用户最终会遇到这个 bug。如果有人有任何指针或想法,我会非常感激。
编辑0:
VS Enterprise 2015,W10M 编译 10586.107 在 Lumia 925 上运行。我希望我知道为什么它没有更新到 .164。
编辑1:
我注意到当崩溃发生时,我的视图中的几个图像都没有加载。有一些 BitmapIcons 从捆绑内容(png)加载,并使用 IValueConverter 从网络加载两个图像,并因此将它们转换为 BitmapImage 和 ImageSources。我检查过转换器是否为空和是否有异常,应该是清晰的。
编辑2:
父视图,触发导航的事件:
    private void SessionList_ItemClick(object sender, ItemClickEventArgs e)
    {
        Frame.Navigate(typeof(ClubPage), e.ClickedItem); // The collection is binded, so the clicked item is a model
    }

在崩溃视图上执行的代码:

    private void ClubPage_Loaded(object sender, RoutedEventArgs e)
    {
        isInfoShowing = false;
        isLogoZoomed = false;
        compositor = ElementCompositionPreview.GetElementVisual(sender as UIElement).Compositor;
        Visual status = ElementCompositionPreview.GetElementVisual(StatusBlock);
        status.Opacity = 0.0f;
        ClubViewModel.Current.ShowIn = false;
        ClubViewModel.Current.ShowComing = false;
    }

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        if (e.Parameter != null)
        {
            ClubViewModel.Current.Club = e.Parameter as Club;
            SplitViewShellViewModel.Current.Title = ClubViewModel.Current.Club.Name.Replace("_", " ");
            SplitViewShellViewModel.Current.TitleBarOpacity = 1.0f;
            ClubViewModel.Current.InLimit = App.RefreshLimit;
            ClubViewModel.Current.ComingLimit = App.RefreshLimit;
            await ClubViewModel.Current.GetClub(); //I'm positive that up until this point the code is executed
            await ClubViewModel.Current.GetPeopleIn();
            await ClubViewModel.Current.GetClubNotifications();
        }
    }

编辑3:

启用本地调试会给我提供以下堆栈跟踪:

enter image description here

当DispatcherTimer滴答时(我的视图中没有),会引发异常。除此之外,我无法理解它的意义。
我已经尝试了我能想到的一切,并重新设计了整个视图。我唯一做的“奇怪”事情是在容器内使用ListView破坏其虚拟化,但我不担心性能问题,因为列表非常小。

1
https://blogs.msdn.microsoft.com/ntdebugging/2014/01/13/debugging-a-windows-8-1-store-app-crash-dump/ - Hans Passant
当你导航到/from页面时,是否对某些内容进行序列化?如果是->您应该将此命名空间\类等添加到Properties中的[ProjectName].rd.xml文件中。 - Mykyta Bondarenko
很可能是由于对象的元数据缺失而导致的问题。您可以在此处找到如何解决 - https://msdn.microsoft.com/zh-cn/library/dn600638(v=vs.110).aspx - Mykyta Bondarenko
@NikitaBondarenko 修改了 Properties/Default.rd.xml,但仍然崩溃 =/. - Gregorio Juliana
e.ClickedItem将被序列化到导航历史记录文件中 - 您需要在rd.xml文件中添加该类型。(我的意思是ClickedItem的实际类型。) - Tamás Deme
显示剩余6条评论
1个回答

3

对我来说,这非常奇怪,但显然上面显示的导航代码并没有在Dispatcher线程上执行...即使它是由UI事件触发的。按照以下方式将调用发送到调度程序即可解决问题:

private async void SessionList_ItemClick(object sender, ItemClickEventArgs e)
{
   await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Frame.Navigate(typeof(ClubPage), e.ClickedItem)); 
}

没有明确的Dispatcher.RunAsync包装器的相同代码在整个应用程序中都能正常工作。每当我遇到UI线程问题时,抛出的异常都是可管理且易于重现的...编译器优化过程中可能发生了什么,可能会触发这种情况?


你好!我在.NET Native运行时和编译器团队工作。很抱歉听到它给你带来了麻烦。听起来你可以在启用.NET Native的DEBUG模式下让问题显现出来,这应该有助于追踪问题。我的一个建议是停止所有第一次机会异常(调试>窗口>异常设置>勾选公共语言运行时框)。许多组件捕获它们无法处理的异常,因此这通常非常有帮助。随时通过电子邮件联系我们dotnetnative@microsoft.com...其他人可能会有更多想法。 - MattWhilden
@MattWhilden 你好!感谢你的光临,非常感激。我按照你说的做了(实际上我都检查了一遍,以防万一),最终复现了这个错误,得到的结果是:Exception。如之前所述,我只在勾选“优化代码”选项时才发现这个问题,除此之外,我想这就是为什么我没有得到更多信息的原因。 - Gregorio Juliana
谢谢Matt,这对我很有帮助。我一直在遇到一个错误,提示找不到ExcectionHelpers.cs文件,结果发现是天气PCL中的问题。 - 27k1
我还有一个应用程序,在调试模式下运行良好,但在发布模式下出现各种调度程序错误。我怀疑这与我通过扩展方法调用调度程序有关。 - William Jockusch
谢谢!这帮了很大的忙。 - Billy Jake O'Connor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接