简体   繁体   English

UWP初始化了几次

[英]UWP initialized several times

I developed a game for UWP with MonoGame. 我使用MonoGame为UWP开发了一款游戏。 With the project I ran into a huge issue . 在这个项目中,我遇到了一个大问题 The application gets initialized several times! 该应用程序被初始化了几次! The game crashed, probably because of heavy initialization code. 游戏崩溃,可能是因为初始化代码过多。

I did not recognize this before publishing the application, because this only happens with the release build mode, and I hadn't tested it in this mode because of long build time. 在发布应用程序之前,我没有意识到这一点,因为这仅在发行版本构建模式下发生,并且由于构建时间较长,因此未在此模式下对其进行测试。 I had made sure that the application did work properly with debug mode on both my own devices as well as on emulators, however when I downloaded it from the store the app crashed on startup so I decided to start analyzing. 我已经确保该应用程序在我自己的设备以及仿真器上都可以在调试模式下正常运行,但是当我从商店下载该应用程序时,该应用程序在启动时崩溃了,因此我决定开始分析。

I finally built it in release mode and debugged it and placed several breakpoints in both App.xaml.cs and GamePage.xaml.cs. 我最终在发布模式下构建它并对其进行调试,并在App.xaml.cs和GamePage.xaml.cs中都放置了几个断点。 I noticed that these breakpoints got hit in an illogical order, jumping back and forth, even skipping lines of code. 我注意到这些断点以不合逻辑的顺序命中,来回跳动,甚至跳过代码行。 Even static boolean values got ignored etc. 甚至静态布尔值也被忽略等。

This happens only in release mode, not in debug mode! 这仅在发布模式下发生,而不在调试模式下发生!

This issue is not MonoGame related as I was able to recreate the same problem with a Blank App (Universal Windows). 这个问题与MonoGame不相关,因为我可以使用空白应用程序(通用Windows)重新创建相同的问题。 How to recreate : 如何重新创建

  1. Create a new Blank App (Universal Windows) 创建一个新的空白应用程序(通用Windows)
  2. Create a method that takes long to excute and call it in the MainPage constructor (see my test method below). 创建一个需要很长时间才能执行的方法,并在MainPage构造函数中调用它(请参见下面的测试方法)。
  3. Set breakpoints in both App.xaml.cs and MainPage.xaml.cs(practically at every line) 在App.xaml.cs和MainPage.xaml.cs中设置断点(实际上在每一行上)
  4. Test the application in debug mode, so that we have something to compare to 在调试模式下测试应用程序,以便我们进行比较
  5. Test the application in release mode. 在发布模式下测试应用程序。 The breakpoints should now be hit in a strange order. 现在应该以奇怪的顺序命中断点。

The debug version runs the heavy method only once, when the release version runs it several times. 调试版本只运行一次Heavy方法,而发行版运行几次。 This is probably caused by some kind of timeout exception, which in turn is caused by the long initialization of MainPage. 这可能是由于某种超时异常引起的,而这种超时异常又是由MainPage的长时间初始化引起的。

My test method(I know that it isn't a method that should be used to measure performance, but it did the trick anyways): 我的测试方法(我知道这不是应该用来衡量性能的方法,但是无论如何它都能成功实现):

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

Does anyone have an idea on how to bypass this or why this is even happening in the first place? 是否有人对如何绕过此方法或为什么首先发生这种方法有想法?

I did also post this on the community.monogame.net. 我也确实将此发布在community.monogame.net上。 Help would be appreciated and thanks in advance! 帮助将不胜感激,并在此先感谢!

In UWP, there are some differences between Debug and Release compile configuration: 在UWP中,“调试”和“发布”编译配置之间存在一些差异:

When you build and run in " Debug " configuration, you are running IL code against the CoreCLR packaged within your application. 当您在“ Debug ”配置中构建并运行时,您将针对打包在应用程序中的CoreCLR运行IL代码 The .NET system assemblies are packaged alongside your application code, and your application takes a dependency on the Microsoft.NET.CoreRuntime (CoreCLR) package. .NET系统程序集与您的应用程序代码一起打包,并且您的应用程序依赖于Microsoft.NET.CoreRuntime(CoreCLR)包。

When you switch to " Release " mode, by default your app utilizes the .NET Native toolchain . 当您切换到“ 发布 ”模式时,默认情况下,您的应用将使用.NET Native工具链 Since the package is compiled to native binaries, the package does not need to contain the .NET framework libraries. 由于该程序包已编译为本机二进制文件,因此该程序包不需要包含.NET Framework库。 In addition, the package is dependent on the latest installed .NET Native runtime as opposed to the CoreCLR package. 此外,该程序包依赖于最新安装的.NET Native运行时 ,而不是CoreCLR程序包。 The .NET Native runtime on the device will always be compatible with your application package. 设备上的.NET Native运行时将始终与您的应用程序包兼容。

And it is important to test in Release mode. 在发布模式下测试很重要。

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. 一个好的经验法则是在整个开发过程中定期以这种方式测试您的应用程序,以确保您确定并纠正.NET Native编译器可能产生的任何问题。 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. 但是,仍有一些东西不能与.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编译版本,因此在整个开发过程中以及在交付之前测试该版本始终是一个好主意。

For more info, please see .NET Native – What it means for Universal Windows Platform (UWP) developers . 有关更多信息,请参见.NET Native –对通用Windows平台(UWP)开发人员意味着什么

Besides .NET Native toolchain, another important difference is that Release configurations by default optimize the code which loses some artifacts used for debugging. 除了.NET Native工具链之外,另一个重要的区别是,默认情况下,Release配置会优化代码,这会丢失一些用于调试的工件。 As a result, trying to debug a Release configuration can result in some issues. 结果,尝试调试发布配置可能会导致某些问题。

It is important to note that the Release configuration is by default fully optimized code (eg 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. 这些优化将对调试体验产生重大影响,包括不可预测的步进和断点行为 (由于代码内联)以及由于内存优化而无法检查大多数变量。

To bypass this, we can create a custom configuration and enable the .NET Native toolchain for that configuration. 为了绕过这一点,我们可以创建一个自定义配置并为该配置启用.NET Native工具链。 Make sure to not optimize code. 确保不优化代码。 For more details please see Debugging .NET Native Windows Universal Apps . 有关更多详细信息,请参见调试.NET Native Windows Universal Apps

As in my test, if I do not enable "Optimize code", the behavior in Release mode is the same as in Debug mode. 与测试中一样,如果我未启用“优化代码”,则Release模式下的行为与Debug模式下的行为相同。 Besides, putting a heavy initialization in constructor is not a good practice. 此外,在构造函数中进行大量初始化不是一个好习惯。 You can start the initialization in some other place such as after page loaded etc. 您可以在其他地方开始初始化,例如在页面加载后等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM