【问题标题】:UWP initialized several timesUWP 初始化多次
【发布时间】:2016-08-28 22:48:46
【问题描述】:

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

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

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

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

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

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

debug版本只运行一次heavy方法,而release版本运行了多次。这可能是由于某种超时异常引起的,而这又是由于 MainPage 的长时间初始化引起的。

我的测试方法(我知道这不是一种应该用来衡量性能的方法,但无论如何它确实起到了作用):

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

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

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

【问题讨论】:

  • 问题是什么?

标签: c# initialization uwp monogame


【解决方案1】:

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

当您在“Debug”配置中构建和运行时,您正在针对应用程序中打包的 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

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

【讨论】:

  • 我尝试在 Loaded 事件内部进行初始化,但这没有帮助。我什至尝试将初始化代码移动到游戏更新的第一个周期,即使这样也没有任何好处,因为内容似乎被加载了好几次(你可以听到背景音乐一遍又一遍地响起) .最烦人的部分是完全相同的代码在其他平台(WP8 和 android)上运行,但在 UWP 上却不行!我可能需要编写一个后台工作人员来解决这个问题,但这不是可取的。
  • 我让应用程序按预期工作,但只有在 Visual Studio 环境之外运行时。但是我希望从商店下载时问题不会再次出现。
猜你喜欢
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 2014-06-21
  • 2020-03-12
  • 2016-02-02
  • 2016-09-29
相关资源
最近更新 更多