UWP 初始化了几次

UWP initialized several times

我使用 MonoGame 为 UWP 开发了一款游戏。对于这个项目,我 运行 遇到了 大问题 。应用程序被初始化了好几次!游戏崩溃,可能是因为大量的初始化代码。

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

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

这只在发布模式下发生,在调试模式下不会发生!

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

  1. 创建一个新的空白应用程序(通用 Windows)
  2. 创建一个需要很长时间执行的方法并在 MainPage 构造函数中调用它(参见下面我的测试方法)。
  3. 在 App.xaml.cs 和 MainPage.xaml.cs 中设置断点(几乎在每一行)
  4. 在调试模式下测试应用程序,以便我们可以进行比较
  5. 在发布模式下测试应用程序。现在应按 st运行ge 顺序命中断点。

debug版本只运行一次heavy方法,而release版本运行多次。这估计是某种超时异常导致的,反过来又是MainPage初始化时间过长导致的。

我的测试方法(我知道这不是一个应该用来衡量性能的方法,但它还是成功了):

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

有没有人知道如何绕过这个或者为什么会发生这种情况?

我也在 community.monogame.net 上做了 post 这个。帮助将不胜感激,并在此先感谢!

在UWP中,Debug和Release编译配置有一些区别:

When you build and run in "Debug" configuration, you are running IL code against the CoreCLR packaged within your application. The .NET system assemblies are packaged alongside your application code, and your application takes a dependency on the Microsoft.NET.CoreRuntime (CoreCLR) package.

When you switch to "Release" mode, by default your app utilizes the .NET Native toolchain. Since the package is compiled to native binaries, the package does not need to contain the .NET framework libraries. In addition, the package is dependent on the latest installed .NET Native runtime as opposed to the CoreCLR package. The .NET Native runtime on the device will always be compatible with your application package.

在 Release 模式下测试很重要。

A good rule of thumb is to test your app this way periodically throughout development to make sure you identify and correct any issues that may come from the .NET Native compiler. There should be no issues in the majority of cases; however, there are still a few things that don’t play so nicely with .NET Native. Four+ dimensional arrays are one such example. Ultimately, your customers will be getting the .NET Native compiled version of your application, so it is always a good idea to test that version throughout development and before shipping.

更多信息,请参阅.NET Native – What it means for Universal Windows Platform (UWP) developers

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

It is important to note that the Release configuration is by default fully optimized code (e.g. code inlining will be applied in many places). These optimizations will have a significant impact on the debugging experience including unpredictable stepping and breakpoint behavior (due to code inlining) and the inability to inspect most variables due to memory optimizations.

为了绕过这个,我们可以创建自定义配置并为该配置启用 .NET Native 工具链。确保不优化代码。详情请见Debugging .NET Native Windows Universal Apps.

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