本文记录9个提升WPF应用程序冷启动性能的策略,面列出的3个技术适用于所有WPF应用程序,无论使用什么组件:
- Ngen.exe
- MultiCore JIT
- ReadyToRun
以下技术是针对DevExpress WPF界面控件的:
- RibbonPage延迟加载
- 对于“Heavy” UI 元素使用LoadingDecorator
- 缓存选项卡
- 按需加载数据
- 预加载主题资源
最后一种技术涉及使用Visual Studio的Performance Profiler(帮助确定与性能相关问题的潜在原因)。
PS:有用控件推荐~DevExpress WPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。
DevExpress技术交流群7:674691612 欢迎一起进群讨论
1. Ngen.exe
Native Image Generator (Ngen.exe) (原生图像生成器)是优化 .NET框架应用程序((.NET/. NET Core项目不支持Ngen)应该考虑的第一个工具,.NET框架项目使用Microsoft中间语言(MSIL)代码生成程序集。在执行应用程序之前,需要将此代码转换为机器代码,从MSIL到机器代码的转换在启动时就开始了——这个过程可能需要大量的时间。
开发人员可以使用Ngen.exe生成已经包含本机代码的原生映像库,需要注意的是,Ngen.exe应该在将要使用应用程序的机器上使用。开发人员可以在自己的机器上运行它来测试性能,但为了优化终端用户的冷启动,需要在用户机器上使用Ngen.exe。
在用户的机器上运行Ngen的最佳方法是将Ngen.exe合并到应用程序安装程序中。在安装过程中,开发人员需要执行以下命令行,Ngen.exe将自动处理与项目相关的所有程序集:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install C:\MyApp.exe
如果开发者将应用程序作为单击一次或存档(并且没有安装程序)分发,则可以在应用程序启动期间从代码中调用Ngen.exe。要在第一次启动时只运行Ngen.exe,为可执行文件计算一个哈希值,并在后续启动时检查这个哈希值:
var savedHash = string.Empty; var assemblyLocation = Assembly.GetEntryAssembly().Location; // Specify a path to the file that stores your executable’s hash. // Create this file or load the saved hash if the file already exists: var hashPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "hash.txt"); if (!File.Exists(hashPath)) { File.Create(hashPath); } else { savedHash = File.ReadAllText(hashPath); } // Obtain the hash for your executable. // Cancel the operation if the application does not have changes: var hash = string.Concat(SHA1.Create().ComputeHash(File.ReadAllBytes(assemblyLocation)) .Select(x => x.ToString("x2"))); if (hash.Equals(savedHash)) return; // Obtain the path to ngen.exe: var dotNetRuntimePath = RuntimeEnvironment.GetRuntimeDirectory(); var ngenPath = Path.Combine(dotNetRuntimePath, "ngen.exe"); // Create a process that runs ngen.exe: var process = new Process { StartInfo = new ProcessStartInfo { FileName = ngenPath, // Pass the path to your executable: Arguments = $"install \"{assemblyLocation}\" /nologo", CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, // Run the process as administrator: UseShellExecute = true, Verb = "runas" } }; // Run the process and save the executable’s hash: try { process.Start(); process.WaitForExit(); File.WriteAllText(hashPath, hash); } catch { // Failed to start. // For example, a user cancelled the UAC prompt. }
Windows 8(以及更新版本的Windows操作系统)包含一个本机映像任务,当计算机空闲时,它会自动为经常使用的.NET Framework 4.5+应用程序生成本机映像。尽管如此,开发者仍然需要手动运行Ngen.exe,因为本机图像任务仅适用于位于GAC或Windows Store应用程序包中的程序集。
下面的图片说明了可以从Ngen.exe启动的好处:
2. MultiCore JIT
或者,开发者可以优化Microsoft中间语言(MSIL)到机器代码的转换,方法是在应用程序启动时异步转换最常用的方法,为此可以使用MultiCore JIT(可用于.NET 和 .NET Framework 4.5+应用程序)。MultiCore JIT记录应用程序使用的方法,并将它们保存到磁盘,当应用程序第二次执行时,保存的方法将在单独的进程中编译为本机代码。
开发者只需要在应用构造函数中使用以下两行代码来启用MultiCore JIT:
public App() { // Defines where to store JIT profiles ProfileOptimization.SetProfileRoot(@"C:\MyAppFolder"); // Enables Multicore JIT with the specified profile ProfileOptimization.StartProfile("Startup.Profile"); }
MultiCore JIT在启动优化方面不如Ngen.exe有效,但另一方面它同时支持.NET Framework和.NET/. NET Core项目。开发者可以将MultiCore JIT与ReadyToRun选项结合使用(稍后将介绍),并从这两种优化策略中受益。
3. ReadyToRun
ReadyToRun (R2R)是一种提前编译(AOT)的形式,用R2R发布的应用程序同时包含MSIL和本机代码段,这在一定程度上消除了即时编译的需要。
R2R选项仅在.NET/. NET Core项目中可用,要启用R2R,请修改“. csproj” / “. vbproj”文件和新增PublishReadyToRun标签:
<PropertyGroup> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup>
要执行此策略,请发布您的项目:
1. 右键单击项目并选择Publish:
2. 在随后的对话框中,选择发布的应用程序将驻留的目标文件夹。
3. 打开发布设置,选择目标运行时,单击Publish按钮:
4. 打开目标文件夹并运行“.exe”文件。
如前所述,R2R可以在.NET/. NET Core应用程序中与MultiCore JIT一起使用,下图说明了可以从R2R和MultiCore JIT中获得的启动好处。
更多DevExpress线上公开课、中文教程资讯请上中文网获取
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:DevExpress控件中文网 [https://www.devexpresscn.com/]
本文地址:https://www.devexpresscn.com/post/3555.html