UWP初始化了好几次

时间:2016-08-28 22:48:47

标签: c# initialization uwp monogame

我用MonoGame为UWP开发了一款游戏。通过该项目,我遇到了一个巨大的问题。应用程序初始化多次!游戏崩溃了,可能是因为初始化代码很重。

在发布应用程序之前我没有意识到这一点,因为这只发生在发布版本模式中,并且由于构建时间较长,我没有在此模式下测试它。我已经确保应用程序在我自己的设备和模拟器上都能正常使用调试模式,但是当我从商店下载应用程序时,应用程序在启动时崩溃,所以我决定开始分析。

我最终在发布模式中构建并调试它并在App.xaml.cs和GamePage.xaml.cs中放置了几个断点。我注意到这些断点以不合逻辑的顺序被击中,来回跳跃,甚至跳过代码行。甚至静态布尔值也被忽略等等。

这仅在发布模式下发生,而不是在调试模式下发生!

此问题与MonoGame无关,因为我能够使用空白应用程序(通用Windows)重新创建相同的问题。如何重新创建

  1. 创建一个新的空白应用程序(通用Windows)
  2. 创建一个需要很长时间才能执行的方法并在MainPage构造函数中调用它(请参阅下面的测试方法)。
  3. 在App.xaml.cs和MainPage.xaml.cs中设置断点(几乎在每一行)
  4. 在调试模式下测试应用程序,以便我们可以与
  5. 进行比较
  6. 在发布模式下测试应用程序。现在应该以一种奇怪的顺序命中断点。
  7. 调试版只运行重一次方法,当发布版本运行多次时。这可能是由某种超时异常引起的,而异常又是由MainPage的长初始化引起的。

    我的测试方法(我知道它不是一种应该用于衡量性能的方法,但它无论如何都是这样做的):

    Random r=new Random();
    while (true)
            {
                if (r.Next(100000) == 100)
                    break;
            }
    

    有没有人知道如何绕过这个或为什么这首先发生?

    我也在community.monogame.net上发布了这个帖子。将提供帮助,并提前感谢!

1 个答案:

答案 0 :(得分:2)

在UWP中,Debug和Release编译配置之间存在一些差异:

  

当您构建并运行“调试”配置时,您正在针对应用程序中打包的 CoreCLR 运行 IL代码。 .NET系统程序集与应用程序代码一起打包,并且您的应用程序依赖于Microsoft.NET.CoreRuntime(CoreCLR)程序包。

     

当您切换到“发布”模式时,默认情况下您的应用会使用 .NET Native工具链。由于包被编译为本机二进制文件,因此该包不需要包含.NET框架库。此外,该软件包依赖于最新安装的 .NET Native运行时,而不是CoreCLR软件包。设备上的.NET Native运行时将始终与您的应用程序包兼容。

在发布模式下进行测试非常重要。

  

一个好的经验法则是在整个开发过程中定期测试您的应用程序,以确保您识别并纠正可能来自.NET Native编译器的任何问题。在大多数情况下应该没有问题;但是,仍然有一些东西与.NET Native不能很好地兼容。四维+阵列就是这样的一个例子。最终,您的客户将获得应用程序的.NET Native编译版本,因此在整个开发过程中和发货之前测试该版本始终是一个好主意。

有关详细信息,请参阅.NET Native – What it means for Universal Windows Platform (UWP) developers

除了.NET Native工具链之外,另一个重要的区别是默认情况下,Release配置会优化丢失一些用于调试的工件的代码。因此,尝试调试Release配置可能会导致一些问题。

  

请务必注意,默认情况下,发布配置是完全优化的代码(例如,code inlining将在许多地方应用)。这些优化将对调试体验产生重大影响,包括不可预测的步进和断点行为(由于代码内联)以及由于内存优化而无法检查大多数变量。

为了绕过这一点,我们可以创建自定义配置并为该配置启用.NET Native工具链。确保不优化代码。有关详细信息,请参阅Debugging .NET Native Windows Universal Apps

在我的测试中,如果我不启用“Optimize code”,则Release模式下的行为与Debug模式中的行为相同。此外,在构造函数中进行大量初始化并不是一个好习惯。您可以在其他地方开始初始化,例如在页面加载后等。