目录
先决条件
介绍
测试应用
使应用程序在Aarch64设备上运行
结果
Aarch64-Native .NET
为Aarch64编译
TSP.WPF.csproj
结论
下一步
将Windows .NET 6 WPF应用程序转换为Windows on Arm (WoA)应用程序需要设置开发环境并对应用程序进行一些更改,使其在没有模拟器的情况下在WoA上运行。
先决条件在本文中,我们将一个示例WPF应用程序移植到WoA环境,使用C#作为我们的编程语言,因此需要一些C#和WPF/XAML知识。
我们将使用Visual Studio 2019作为IDE。您应该知道如何创建项目、类和WPF表单。
介绍我们看到了WoA如何执行几乎所有.NET应用程序。它使用x86仿真层来执行不是为Aarch64处理器编译的程序。尽管仿真层的性能尽可能高,但我们注意到为WoA本地编译的应用程序可以快11倍。
微软试图将WPF挤入.NET 5框架中的Arm,但他们无法及时完成,因此我们创建了一个以原生模式运行在WoA上的UWP应用程序。
在.NET 6中,将包含用于Arm的WPF,让我们看看如何使用它。
注意:我们将使用在撰写本文时可用的最新测试版,因此发布的版本中可能会有一些变化。
测试应用我们将使用一个测试应用程序来解决一个众所周知的问题:旅行商问题(TSP)。
该应用程序的主要目的是能够在Aarch64上执行模拟版本和本机.NET 6 WPF之间的速度基准测试。所以我们需要一些CPU密集型的东西,最好还有一些图形化的东西来测试.NET 6中WPF的功能。
要以蛮力方式求解TSP,需要计算所有点之间的所有可能路径(组合)。这在大约12个点的情况下仍然是可行的,但是它变得非常慢。
要计算N个点之间所有可能的路径需要计算N!路径。例如,找到20个点之间的最佳路径需要20个!(2,432,902,008,176,640,000)计算。即使在一台非常快的计算机上,我们也不会活到看到结果。
我们显然需要另一种解决方案。有多种可能性,但我们将实现遗传算法(GA)来为该问题找到最佳局部解决方案。实际实现超出了本文的范围。您可以在GVerelst/TravelingSalesman 找到该应用程序的源代码:使用遗传算法找到最佳路径。
这些是有关应用程序的要点:
- “生成路径”按钮生成一个新的随机路径。默认情况下,路径将有20个点。
- 种群大小决定了遗传算法的种群长度。默认情况下,它设置为5,000。这意味着对于每次迭代
- 计算5,000条路径的距离。
- 5,000条路径按其长度排序。
- 通过使用交叉和变异算法生成了5,000条新路径。
- 最佳路径显示在画布上。
- 随机种子用于伪随机生成器。从相同的数字开始将始终生成相同的数字序列。这样我们可以更好地比较完成算法的时间。
在这个版本中没有任何错误处理。在其中一个字段中输入非数字内容或在没有首先生成路径的情况下开始计算将使程序崩溃。如果要验证数字输入,请查看以下Stack Overflow文章:C# WPF How to use only numeric value in a textbox - Stack Overflow。
这是算法经过 1,000,000 次计算后的结果:
这不能保证是最好的可能路径,但它已经过大量优化并且很可能是一个可以接受的解决方案。
初始应用程序是为.NET 5编译的,因此它不会在Arm设备上运行。
使应用程序在Aarch64设备上运行对我们来说幸运的是,Microsoft现在正在.NET 6中实现WPF。在撰写本文时,版本6.0.0-preview.3已经可用。
尚不支持在Windows on Arm上直接安装Visual Studio 2019,它是一个更快的开发|部署|使用现有X64开发人员机器的调试周期
可以在Arm上的Windows上运行Visual Studio,但它将在x86仿真模式下运行。这太慢了,无法舒适地工作,所以我们使用x64 Windows机器。
就我而言,我在Microsoft Azure中使用B4ms虚拟机,该虚拟机具有4个CPU内核、16GB内存、8个最大附加磁盘(远远超出我们的需要)和2880 IOPS磁盘吞吐量,以确保良好的性能:
要准备开发机器,首先将Visual Studio更新到最新版本(版本16.11或更高版本)。最简单的方法是使用Visual Studio安装程序。然后安装.NET 6 SDK。
如果要使用Visual Studio 2019中的预览功能,则需要明确说明。在“选项”对话框(“工具” >“选项”)的搜索字段中输入“预览”,然后在左侧的树中选择“预览功能”。搜索“使用.NET Core SDK的预览版”并选中复选框。需要重新启动Visual Studio。
当您重新打开Visual Studio时,您会在目标框架的下拉列表中找到.NET 6.0。
在WPF和GA项目中将目标框架设置为.NET 6.0,也可以在测试项目中选择。现在我们准备重新编译应用程序。
结果这是一个使用模型-视图-视图模式 (MVVM)模式的WPF应用程序,带有一些图形(绘制路径)和一个后台工作线程。所以它不是最基本的WPF应用程序。然而,构建不会给我们任何错误或警告。
它运行没有任何问题,在与程序的.NET 5版本大致相同的时间内找到结果路径。这对于框架的最终版本来说看起来很有希望!
Aarch64-Native .NET在我们构建和运行我们的应用程序的Aarch64原生版本之前,我们首先需要在Arm设备上安装.NET 6预览版,您可以在此处下载。我们甚至不需要在安装后重新启动设备。
请注意,如果您已经安装了x86 .NET Core或.NET 5 SDK,则64位Arm .NET SDK不会覆盖其他SDK的PATH变量——至少在最新的.NET 6预览版中如此。这可能会在.NET 6发布周期的后期发生变化。要在安装.NET 6预览版后进行检查,请在终端中运行dotnet --info。你会看到这样的东西:
PS C:\> dotnet --info
.NET SDK (reflecting any global.json):
Version: 5.0.100
Commit: 5044b93829
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-x86
Base Path: C:\Program Files (x86)\dotnet\sdk\5.0.100\
检查RID字段。如果它显示win10-arm64,那么你就可以开始了,你可以跳到下面的为Aarch64编译部分。如果没有,您需要更新系统路径以包含arm64原生.NET SDK。为此,请打开Windows设置应用程序,然后搜索“环境变量”:
通过双击变量来验证用户变量中的Path变量:
确保您有一个条目为C:\Program Files\dotnet,如果您看到一个条目为C:\Program Files(x86)\dotnet,请将其删除。现在,如果你运行dotnet –info,你应该看到:
PS C:\Users\gvere> dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.100-preview.3.21167.6
Commit: fa9dcf862f
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-arm64
Base Path: C:\Program Files\dotnet\sdk\6.0.100-preview.3.21167.6\
Host (useful for support):
Version: 6.0.0-preview.3.21167.1
Commit: 0f64b267ac
这可能只是我的设备上的问题,但如果您遇到同样的问题,您现在知道该寻找什么了!我不是唯一遇到此问题的人,如果您想了解更多信息,请查看:Windows找不到最新安装的.NET SDK——堆栈溢出。
为Aarch64编译这是使一切正常工作的最后步骤。
在开发机器上打开TSP.WPF项目并添加元素,如下所示:
TSP.WPF.csproj
WinExe
net6.0-windows
win-x64;win-arm64
true
Gaston Verelst
Faq.be bvba
接下来,我们需要创建一个发布配置文件:
1、右键单击TSP.WPF项目并选择发布...
2、对于目标,选择Folder并点击Next。
- 对于特定目标,也选择Folder并单击Next。
4、为 要发布的二进制文件选择一个位置。通常默认值是好的。如果您使用共享文件夹部署到您的设备,您可以在此处选择该文件夹,以便您可以跳过复制文件。
5、单击完成以创建初始发布配置文件。
6、在更 多选项下单击编辑。设置如下值,然后单击Save。
7、单 击发布。
Visual Studio现在编译我们项目的一个版本,该版本可在Aarch64设备上本地执行:
将此文件夹复制到您的设备并运行该应用程序。现在它在Arm设备上以64位本机模式运行,在.NET 6上使用WPF!
结论找到我们之前使用的相同路径的时间现在是1分23秒,这与开发VM大致相同。我们可以再次说运行.NET 6和Aarch64设备的性能非常好。
在.NET 6上为WPF构建项目需要一些额外的步骤,但不需要更改代码。
除了路径问题之外,在Arm机器上的64位Windows上安装.NET 6很简单。如果您同时运行win10-x86和win10-arm64 .NET SDK,请确保检查这一点。
本机运行WPF应用程序只需要在.csproj文件中进行一些更改,并在选择正确的目标运行时发布它。完成此操作后,应用程序将毫无问题地运行!
下一步尽管.NET 6仍处于预览阶段,但WPF支持已经运行良好。正如我们所见,采用现有的x86/x64 WPF应用程序并在基于Aarch64的Windows机器上本地运行它是相对简单的。
如果WPF应用程序通过PInvoke调用本机C/C++库或使用包装C/C++库的NuGet包,则需要谨慎使用。如果这样做,您将需要这些库的Aarch64版本来本地运行您的应用程序。
如果您遇到问题,此线程是开始寻求帮助的好地方。
有关.NET 6的更多信息,请查看宣布.NET 6 Preview 3 | .NET博客(microsoft.com)。
Visual Studio 2019