使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

2015年7月30日

本文作者是 Managed Languages 團(tuán)隊(duì)項(xiàng)目經(jīng)理 Lucian Wischik。

不久前,Visual Studio 2015上新增 Windows 10 應(yīng)用的開發(fā)工具——Universal Windows App開發(fā)工具。這個(gè)發(fā)布擁有重大意義:開發(fā)者可利用最新的 .NET 技術(shù)開發(fā) Universal Windows Platform (「UWP」) 應(yīng)用,這些應(yīng)用程序可運(yùn)行在任一款 Windows 設(shè)備上——Windows 手機(jī)、平板電腦或者筆記本電腦、PC 機(jī)、Xbox 游戲機(jī),以及 Windows 新出的 HoloLens、Surface HubRaspberry Pi 2(IoT 設(shè)備)等等。

安裝 UWP 工具

開發(fā)者可下載安裝免費(fèi)的 VS2015 的社區(qū)版,該版本默認(rèn)安裝 UWP 工具。如需安裝專業(yè)版或是企業(yè)版,可從 VisualStudio.com 處下載安裝。在安裝過程中,選擇「Custom(自定義)」安裝 Universal Windows Apps 開發(fā)工具。

如果已經(jīng)安裝了 Visual Studio 2015,有兩種方式獲得 Universal Windows Apps 開發(fā)工具:

  • 下載并運(yùn)行 Windows Tools installer。

  • 從控制面板打開「程序和功能(Programs and Features)」,選擇 「Visual Studio 2015」并點(diǎn)擊「更改(Change)」。然后在安裝過程中,點(diǎn)擊「修改( Modify)」,選擇「Tools for Universal Windows Apps」。

使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

UWP 新功能

只要是 .NET 開發(fā)者都會(huì)喜歡 UWP 提供的特性——

  • UWP 應(yīng)用在安裝 Windows 10 操作系統(tǒng)的臺(tái)式機(jī)上以窗口化視圖運(yùn)行。
  • UWP 應(yīng)用在任一款 Windows 10 設(shè)備上均可運(yùn)行——手機(jī)、XBox、HoloLens 甚至是 Raspberry Pi 等物聯(lián)網(wǎng)設(shè)備。
  • UWP 應(yīng)用利用了最新 .NET Core 的技術(shù)優(yōu)勢(shì),通過使用 .NET Core 的最新版本的新加功能簡化應(yīng)用程序的開發(fā)。
  • 應(yīng)用程序和業(yè)務(wù)邏輯核心的 .NET,同樣可在如 ASP.NET 5 等平臺(tái)(支持 .NET Core 的平臺(tái))上運(yùn)行。
  • UWP 應(yīng)用在程序內(nèi)部署縮減后的 .NET 副本,以便應(yīng)用總是使用經(jīng)過驗(yàn)證的 .NET 版本 。
  • UWP 應(yīng)用使用 .NET Native 技術(shù),在客戶機(jī)下載代碼前,.NET Native 可生成高度優(yōu)化的原生機(jī)器代碼。.NET Native 技術(shù)的使用,使得應(yīng)用程序的啟動(dòng)時(shí)間縮短、電量消耗降低和性能加快。
  • 用戶可很方便地在 Windows 商店內(nèi)購買、安裝和升級(jí) UWP 應(yīng)用程序。
  • UWP 應(yīng)用程序完美地結(jié)合了用于詳細(xì)測試和分析的Application Insights插件——一個(gè)了解用戶需求和提高應(yīng)用程序質(zhì)量的重要工具。

新工具帶來的新用途——

  • 使用 .NET 編寫 Windows 10 UWP 應(yīng)用程序。
  • 編寫用于 .NET Core 的 Portable Class Libraries
  • 相比之前 Windows Store 或 Phone 應(yīng)用,UWP 應(yīng)用程序中可以使用更多的 .NET 外部工具,包括 System.Net.Sockets、WCF ClientSystem.Numerics.Vectors 和新的 Diagnostics APIs。
  • NuGet 3.1(由文件「project.json」識(shí)別)可用于不同類型項(xiàng)目項(xiàng)目。

UWP 開發(fā)入門

下面是關(guān)于 UWP 開發(fā)的一些實(shí)用的概述和教程:

在本篇博客中,筆者將會(huì)介紹:作為 .NET 開發(fā)者,需要注意的哪些改進(jìn)的地方——其他教程不會(huì)涉及的內(nèi)容。首先需要建立平臺(tái),下面十張圖中涵蓋了 .NET UWP 開發(fā)過程中全部 Microsoft 工具。

File > New > C#/VB > Windows > Universal 開始編寫一個(gè)全新的 UWP 應(yīng)用。改進(jìn)后的 NuGet 比 VS2015 RC 要快得多。開發(fā)者同樣可創(chuàng)建一個(gè)兼容 UWP、ASP.NET 5 和 .NET 4.6 的 Portable Class Libraries (PCLs) 。

使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

Solution Explorer > References References利用獨(dú)特的圖標(biāo)顯示 NuGet 程序包。「Microsoft.NETCore.UniversalWindowsPlatform」是其中比較重要的一個(gè)包;它包含了 .NET Core 運(yùn)行時(shí)和框架。 project.json 文件取代 packages.config 驅(qū)動(dòng) NuGet 3.0。NuGet 3.0 與 NuGet 2.0 相比,運(yùn)行速度更快且更加復(fù)雜。

使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

Adaptive XAM 開發(fā)人員經(jīng)常設(shè)計(jì)「自適應(yīng)的 UIs」以便其適應(yīng)于不同設(shè)備、不同形式?,F(xiàn)在隨著 XAML 的發(fā)展,ViewState triggers、更多設(shè)備預(yù)覽和現(xiàn)場 XAML Tree 調(diào)試等方式使得這項(xiàng)任務(wù)變得非常容易。同樣, 在高性能數(shù)據(jù)綁定使用 x:Bind。

使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

Adaptive code 一個(gè)優(yōu)秀的通用應(yīng)用程序的關(guān)鍵在于在不同的設(shè)備間可盡可能多的分享代碼,與此同時(shí)還要保障每個(gè)設(shè)備上都有最好的應(yīng)用體驗(yàn)。開發(fā)者可通過調(diào)用特定平臺(tái) WinRT APIs,在 .NET 中編寫自適應(yīng)代碼。這比使用 Reflection(自適應(yīng)代碼的前沿技術(shù))方式要好的多。

使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

Fast graphics:Win2dSystem.Numerics.Vectors。對(duì)于快速繪圖,可利用Win2d 庫——是DirectX上 .NET 一個(gè)「精致」的封裝。當(dāng)然,這里仍可以使用SharpDX 或者 MonoGame。System.Numerics.Vectors 通過 CPU 的 SIMD 指令進(jìn)行快速矢量和矩陣運(yùn)算。在來利用這些技術(shù)后,在中端 Nokia 635計(jì)算 Mandelbrot Fractal 僅需70毫秒。

WCF,HTTP/2 and Sockets目前 .NET 庫包括WCF和 AddServiceReference,兩者之前均不適用手機(jī)應(yīng)用程序。HttpClient已被重寫:重寫后性能更好,并且支持HTTP/2協(xié)議。這里同樣需要System.Net.Sockets,Windows Store 應(yīng)用中期待已久 .NET 特性。

Improved debugging and EnC 現(xiàn)在,開發(fā)者在仿真器上調(diào)試時(shí)可以使用「Edit and Continue (EnC)」。整個(gè)調(diào)制器引擎早已修改——在即時(shí)和觀察窗口中支持 lambdas 和 LINQ 表達(dá)式,同時(shí)與之前相比,在更多地方支持 EnC。一些開發(fā)者在 EnC 上編寫整個(gè)程序的代碼??靽L試下吧!

使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

.NET Native 當(dāng)處于 Release 模式中,應(yīng)用程序通過新「.NET Native」編輯器編譯。這就將其轉(zhuǎn)化為高度優(yōu)化的原生機(jī)器代碼——應(yīng)用程序啟動(dòng)時(shí)間縮短、電量損耗降低和整體性能加快。

Store submission 開發(fā)人員將十分喜愛新的統(tǒng)一開發(fā)者中心( Developer Center)。在提交一個(gè)應(yīng)用時(shí),向?qū)?huì)提交應(yīng)用程序的 MSIL。商店使用 .NET Native 進(jìn)行編譯,將應(yīng)用程序優(yōu)化為原生機(jī)器代碼(這是一個(gè)很難的反向工程,就像 C++ 代碼那樣),并將其部署到用戶設(shè)備中。

Application Insights and Diagnostics 新項(xiàng)目中默認(rèn)安裝Application Insights 插件。該插件為應(yīng)用程序提供崩潰和使用時(shí)的詳細(xì)分析。應(yīng)用商店中排名較高的應(yīng)用程序都已知曉排名較高的原因是接收和分析響應(yīng)。在ETW中有著更為豐富的追蹤功能。

.NET Native

.NET Native 是預(yù)(「AOT」)編譯技術(shù):在編譯的時(shí),它將代碼轉(zhuǎn)為機(jī)器代碼。這與傳統(tǒng)的 .NET 使用的實(shí)時(shí)(「JIT」)編譯技術(shù)不同,在運(yùn)行時(shí)延遲本地編譯直到它第一次執(zhí)行。.NET Native 更接近與 C++ 編譯器。事實(shí)上,它的工具鏈中有 Visual C++ 編譯器,在 Windows Store 中,該工具用于提交應(yīng)用程序(并非最終用戶設(shè)備)。它能夠快速地、精確地、獨(dú)立地生成代碼。

.NET Native 對(duì)終端用戶有著巨大的好處:應(yīng)用啟動(dòng)時(shí)間縮短60%,并且優(yōu)化應(yīng)用程序的內(nèi)存占用。在一些 UWP 應(yīng)用程序上,筆者曾成功地將啟動(dòng)時(shí)間由1秒縮短到110ms,測試機(jī)型號(hào)為 Nokia 635。這都?xì)w功于 .NET Native 和 VS 2015 新的perf-tips 功能和 Diagnostics Tools 窗口。

目前在 .NET 團(tuán)隊(duì)博客上已經(jīng)發(fā)布了很多關(guān)于 .NET Native 預(yù)覽版的文章。UWP中創(chuàng)新點(diǎn)在于它是第一個(gè)使用 .NET Native 的產(chǎn)品。對(duì)于大部分情況而言,.NET Native 是透明的:當(dāng)在 Release 模式下使用時(shí),它編譯進(jìn)行的相當(dāng)隱蔽;Release 版本建立需要更長的時(shí)間,并且調(diào)試稍微差一點(diǎn),性能特點(diǎn)也稍微有點(diǎn)不同;但除此之外應(yīng)用程序能繼續(xù)正常運(yùn)行并實(shí)現(xiàn)功能。Debug 版本主要依靠 CoreCLR,如你期望的那樣,有著杰出的調(diào)試體驗(yàn)。

盡管 .NET Native 早在一年前就已公開預(yù)覽,對(duì)于很多人亂來說,這仍將是在 UWP 中第一次使用。出于這個(gè)原因,筆者會(huì)更詳細(xì)的介紹下它是如何工作的。不僅因?yàn)橐源藶楹溃瑫r(shí)也為了滿足讀者的好奇心。

.NET Core Framework

上周的一篇博文中已經(jīng)討論過了 .NET Core Framework ("CoreFX"):

  • .NET Core 是現(xiàn)代化設(shè)備和云工作負(fù)載使用的 .NET 最新版本。.NET Core 以通用化為目的,并采用模塊化部署,可在不同環(huán)境下的多種工作負(fù)載移植和使用。

CoreFX 常用于 UWP 應(yīng)用程序。它是曾用于 Windows Store 開發(fā)的 .NET APIs 的擴(kuò)展包。

這里重點(diǎn)介紹下 UWP 開發(fā)者比較感興趣的 .NET Core FX:

  • System.Net.Sockets(曾用于 UDP 通信)曾用在 WinRT 應(yīng)用程序上。其方式是使用特定的 WinRT UDP APIs?,F(xiàn)在 System.Net.Sockets 已經(jīng)成為 .NET Core 的一部分,所以可被 UWP 應(yīng)用使用。事實(shí)上,開發(fā)者可以在其他的 .NET 應(yīng)用程序上共享 Sockets 代碼。注:這里正在致力于 System.Net.Sockets 的開源工作。
  • HttpClient(類似許多 .NET Core FX 的低 level 部分)需要進(jìn)行不同的部署才能在不同的平臺(tái)運(yùn)行。在 UWP 應(yīng)用中,它被部署在 WinRT HTTP 棧的頂部。其默認(rèn)的情況下使用HTTP/2協(xié)議,以獲得更低的延遲和更少的往返通信次數(shù),當(dāng)然前提是服務(wù)器支持該協(xié)議。
  • WCF Clien(和關(guān)聯(lián)的Add Service Reference dialog)曾在 Windows Phone Appx 項(xiàng)目中使用。但自從它變成 .NET Core 的一部分后,就經(jīng)常被用于 UWP 應(yīng)用程序中了。
  • System.Numerics.Vectors提供了向量和矩陣類型,該類型常用于 CPU 的 SIMD 操作碼——單指令多數(shù)據(jù)。矢量和矩陣的運(yùn)算速度相比于正常的「單指令單數(shù)據(jù)」操作碼要快得多。
    -System.Diagnostics.Tracing。目前調(diào)度事件中,EventSource 可發(fā)送更豐富的有效負(fù)載到 Windows 事件跟蹤(ETW)中。

CoreFX 另外兩個(gè)令人興奮的方面是:開源和解除了與 Windows 和 Visual Studio 發(fā)布捆綁。每個(gè)開發(fā)者都可以參與其中并作出自己的貢獻(xiàn),.NET 團(tuán)隊(duì)每天都有所貢獻(xiàn)。該團(tuán)隊(duì)與社區(qū)一起致力于擴(kuò)展 CoreFX,添加更多的 APIs。只要這些接口能加入其中,就能為 UWP 應(yīng)用程序所用。由于 project.json 和 NuGet 存在,任一 UWP 開發(fā)人員都能使用最新版 .NET Core FX Packages(只要它們可用)——僅通過「Manage NuGet Packages」對(duì)話框即可。

注意:File>New 可以生成一個(gè)具有全套官方 Microsoft NET Core 組件的 UWP 應(yīng)用程序,這些與 UWP 應(yīng)用相關(guān)組件是用于其測試。如果想其他的或者尚未開發(fā)的 Microsoft 庫,不能再使用「References > Add References」下——相反地,而是在「References > Manage NuGet References」中。

如果想自行編寫一個(gè) .NET Core 庫,大可試著開發(fā)任一 .NET4.6、UWP 或 ASP.NET 5 平臺(tái)可用的 PCLs。

Universal Projects

利用 UWP 可以編寫通用的應(yīng)用——單一的 VS 項(xiàng)目、單一的代碼庫、單一上傳到 Windows Developer Center --即便其運(yùn)行在多個(gè)「家族設(shè)備」(桌面、手機(jī)、Xbox 等等)。利用 UWP,應(yīng)用程序代碼不再需要使用#ifdefs 或 Shared Projects。通過此方法,應(yīng)用程序開發(fā)和維護(hù)將會(huì)變得更加容易。

MSDN 上的「UWP 應(yīng)用程序指南」對(duì)如何讓應(yīng)用程序在不同的設(shè)備上界面看起美觀這一問題做了很好的解釋。好的方面是,通過 UI 調(diào)整能使得應(yīng)用程序在桌面不同大小的窗口看起來都很美觀,在不同設(shè)備同樣也可做到這一點(diǎn)。

從 .NET 方面來看,最有趣的技術(shù)就是采用自適應(yīng)代碼。例如:


使用 .NET 平臺(tái),如何玩轉(zhuǎn) Universal Windows 應(yīng)用?

在 Windows 10 電腦桌面上,我的應(yīng)用程序及其美觀,但是在 Windows 手機(jī)界面上,它僅僅顯示 Status Bar(狀態(tài)欄)。如果使用了StatusBar.HideAsync,應(yīng)用程序應(yīng)該會(huì)看起來更好看一點(diǎn)。然而StatusBar是電腦桌面上不存在的類型。處理此情況的代碼看起來非常簡單——WinRT API: Windows.Foundation.Metadata.ApiInformation.IsTypePresent用于檢測應(yīng)用程序正運(yùn)行的設(shè)備上有無 WinRT 類型,并且它只會(huì)調(diào)用該案例中特定平臺(tái)方法。

有時(shí)候很難記住哪個(gè) API 需要 IsTypePresent 保護(hù)。為此,這里開發(fā)一個(gè)名為PlatformSpecific.Analyzer的 NuGet 包,開發(fā)者可以將其添加到項(xiàng)目中:如果忘記保護(hù)某個(gè)接口,它將會(huì)在 IDE 中顯示警告信息。

有趣的是,這種自適應(yīng)代碼目前僅在 UWP 平臺(tái)上的 .NET 中可用,并且是只針對(duì) UWP 類型。剛?cè)腴T的 .NET 專家可能比較想了解詳情。對(duì)于 Debug builds,CoreCLR需要( JIT)實(shí)時(shí)編譯 SetupAsync 方法,想要做到這一點(diǎn)必需要清楚代碼主體中每種類型和方法的元數(shù)據(jù),同時(shí)還要弄明白那些即便不運(yùn)行的分支中方法類型。 UWP 處理此問題需要建立一個(gè)本地應(yīng)用程序文件「windows.winmd」,該文件包含全部 UWP 設(shè)備和各個(gè)版本中使用過 WinRT 類型和方法的元數(shù)據(jù)。對(duì)于 Release builds,.NET Native 將必要的元數(shù)據(jù)最終編譯成機(jī)器代碼,其格式一般是 COM IIDs 或者虛擬表形式。

因?yàn)閷F(xiàn)有的代碼庫移植到 UWP 十分重要,這里不得不提自適應(yīng)應(yīng)用程序中PCLs的最后一個(gè)話題。如果編寫一個(gè)「8.1 通用PCL」,即能同時(shí)在 Windows 8.1 和 Phone 8.1 使用??蓞⒖?UWP 應(yīng)用程序中使用 PCLs 的方式,將其做的完美。這是因?yàn)槟切?PCLs 只能稱之為 WinRT APIs 的子集,所有 UWP 平臺(tái)都兼容該子集。

NuGet 3.0和「project.json」

在 .NET 應(yīng)用程序中,NuGet 事實(shí)上已經(jīng)成為包管理的標(biāo)準(zhǔn)。這里本打算將 .NET Core 作為 NuGet 包進(jìn)行部署,但現(xiàn)有的 NuGet 2.0 客戶端和 packages.config(盡管前景很好),卻不是擴(kuò)展到100+子包后 .NET Core的最佳選擇——速度太慢,又不夠靈活。NuGet 3.0解決了這些問題。最初是用于 ASP.NET 5中,現(xiàn)在 UWP 也在使用。

如果一個(gè)項(xiàng)目中使用了 project.json 文件而非 packages.config,同樣可以說該項(xiàng)目使用了 Nuget 3.0。開發(fā)人員同樣可以將 project.json 添加到任一現(xiàn)有的 .NET 項(xiàng)目中,同樣會(huì)起作用(首先需要項(xiàng)目卸載再重載)。下面是 project.json 的工作方式:

  1. 當(dāng)安裝一個(gè) NuGet 包時(shí),project.json 文件中將會(huì)自動(dòng)添加一個(gè)引用,可以在 SolutionExplorer > References 下查看它。
  2. 在 Build 之前,VS 確保所有的 NuGet 包(以及相關(guān)文件)成功的下載到用戶設(shè)備上的緩存中心內(nèi),由它選擇當(dāng)前項(xiàng)目目標(biāo)/架構(gòu)所要使用的包。
  3. 在 Build 時(shí),如果存在 project.json 文件,MSBuild 將會(huì)讀取該文件并引用相應(yīng)的 DLLs 和它包含的 .targets 文件。

這里看下 project.json 帶來的好處:

  • .vbproj/.csproj 將不再包含任何 NuGet 引用:它們將完全分開。這將使得源代碼控制和合并沖突解決更加容易!
  • 可以修改應(yīng)用程序的目標(biāo)平臺(tái),更改 Debug/Release 以及 x86/x64/ARM/ 任一 CPU,NuGet 將會(huì)實(shí)現(xiàn)這些設(shè)置。
  • 在同一個(gè)需要 NuGet 的項(xiàng)目中,可以在兩個(gè)不同的目錄下分別部署不同的解決方案。當(dāng)需要在兩個(gè)庫中工作時(shí),這將十分有效。
  • Solution Explorer > References 將會(huì)更加簡潔,因?yàn)樗话税惭b時(shí)選擇的包而非全部相關(guān)的包。卸載 NuGet 包也變得更加方便,同樣是因?yàn)橹恍栊遁d選定的包而非全部相關(guān)的包。
  • 包可在全局(每臺(tái)機(jī)器上的每個(gè)用戶)內(nèi)緩存,省略了單個(gè)解決方案使用時(shí)下載+解壓縮的步驟。
  • File > New 和Manage NuGet Packages > Install 兩者速度都有所加快。
  • 在 NuGet 包升級(jí)和版本不匹配時(shí),控制更加精確。

請(qǐng)?jiān)?NuGet Team BlogNuGet Home repo 查看更多關(guān)于 NuGet 的資料。兩者均是與該團(tuán)隊(duì)討論 NuGet 變化的最佳場所?,F(xiàn)知的一個(gè)問題(并期望在未來升級(jí)版中解決該問題):UWP 應(yīng)用中 Solution Explorer References 節(jié)點(diǎn)下顯示 NuGet 包所有相關(guān)的文件,正如 ASP.NET 5同樣具有該功能,這是一個(gè)好的改變嗎?

一些 NuGet 包安裝在 UWP 應(yīng)用時(shí),其工作方式會(huì)發(fā)生變化。如果你發(fā)現(xiàn)某些包出現(xiàn)異常情況時(shí),請(qǐng)?jiān)谠撡N底部的評(píng)論區(qū)留言。

  • SharpDX.Toolkit 2.6.3 升級(jí)之后的 SharpDX 3(目前仍是 Alpha 版本)在 UWP 應(yīng)用中表現(xiàn)出色。SharpDX 工具包已被廢棄,并將不會(huì)在版本3中添加,同時(shí)也將不會(huì)安裝到 UWP 應(yīng)用中。這里將考慮 ParadoxMonoGame 作為其在 SharpDX 上代替工具包。
  • MvvmLight 該 NuGet 包可在 UWP 應(yīng)用上正常工作,除了在安裝時(shí)需要多加一個(gè)額外步驟。安裝時(shí)能自動(dòng)修改 App.xaml 文件和向項(xiàng)目中添加其他一些文件。但這并不適用于 UWP 應(yīng)用,所以這里需要手動(dòng)修改或者使用 MvvmLight VSIX
  • Sqlite-net 盡管 UWP 應(yīng)用中不再安裝該 NuGet 包,與其類似的Sqlite.Net-PCL(同一作者)包表現(xiàn)搶眼。
  • LiveSDK 該 NuGet 包盡管仍會(huì)安裝,但沒有實(shí)際引用 DLLs。在短期工作中,可以自行手動(dòng)添加引用 Microsoft.Live.dll(如何確定 DLL 文件的位置?最簡單的方法是在 UWP 應(yīng)用中添加 LiveSDK 引用,然后將 NuGet 下載到%USERPROFILE%.nuget\packages\LiveSDK 路徑下)。另一個(gè)選擇,還可以使用該文檔描述的 Windows.Security.Authentication.OnlineID,至于 OneDrive,可通過 HttpCliet 使用 REST APIs。

順便說一句,「現(xiàn)代化」PCLs 默認(rèn)使用 project.json——例如某些可用于 .NET4.6、UWP 和 ASP.NET 5 Core 的 PCLs。

UWP 應(yīng)用使用 CoreCLR 進(jìn)行調(diào)試,而 .NET Native 使用 CoreCLR Release 下圖顯示了當(dāng)編譯、調(diào)試和提交 UWP 應(yīng)用到商店時(shí)發(fā)生的狀況。VB 和 C# 編譯器在 MSIL 不斷生成 DLLs 文件。這是接下來發(fā)生的變化...

Debug build: CoreCLR. When you build your UWP app in Debug mode, it uses the 「.NET Core CLR」 runtime, the same as used in ASP.NET 5. This provides a great edit+run+debug experience – fast deploy, rich debugging, Edit and Continue. It also means

調(diào)試版本:CoreCLR。當(dāng)在 Debug 模式下編譯 UWP 應(yīng)用時(shí),運(yùn)行的是「.NET Core CLR」,在 ASP.NET 5 中同樣如此。這提供了一個(gè) edit+run+debug 極好體驗(yàn)——快速部署、多次 Debug、Edit 和 Continue。

發(fā)布版本:.NET Native。當(dāng)在 Release 模式下編譯程序時(shí),它需要額外的30秒將 MSIL 和引用轉(zhuǎn)換為優(yōu)化的原生機(jī)器代碼。這里正在努力縮短此時(shí)間。通過「tree-shaking」方式刪除從未調(diào)用過的代碼。并在「Marshalling Code Generation」預(yù)編譯序列化代碼以便在運(yùn)行中無需反射。優(yōu)化全部程序代碼。本機(jī)代碼的優(yōu)化和編譯生成單一本地 DLL 文件。可以在 bin\x86\Release\ilc 目錄下找到此文件。

**.NET Core:CoreCLR和 .NET Native 兩者均是「.NET Core Runtimes」。它們可以同時(shí)使用和運(yùn)行相同的 .NET Core 庫(CoreFX),所以在 Debug 模式和 Release 模式下不存在差異。在 Windows 8/8.1 中, .NET Framework 曾用于 .NET 的底層部署。在 Windows 10 中使用 .NET Core,可在調(diào)用新 CoreFX 庫的同時(shí)提供 Debug 和 Release 兩種模式。

Store submission。當(dāng)開發(fā)了一個(gè)準(zhǔn)備提交到 Windows Store 商店的 Appx 包時(shí),該 Appx 附加包中包含 MSIL。然后 Windows Store 進(jìn)行 .NET Native 編譯。這就減輕了一些人對(duì) .NET Core FX「局部應(yīng)用部署」的擔(dān)憂。他們擔(dān)心如果在 .NET 中出現(xiàn)安全漏洞怎么辦。在過去,通常的解決方法是進(jìn)行 Windows 更新?,F(xiàn)在,通過識(shí)別 Appx 包是否易受攻擊,然后和其開發(fā)者一起進(jìn)行修復(fù)解決。

.NET Native 開發(fā)技巧

在發(fā)布模式下測試 請(qǐng)?jiān)?Release 模式下定期測試的應(yīng)用程序。Release 模式使用了 .NET Native。如果定期測試(比如四小時(shí)測試一次),將能夠及時(shí)發(fā)現(xiàn)問題,如 Expression.Compile 的不同性能。如果在測試中發(fā)現(xiàn)問題需要調(diào)試時(shí),當(dāng)心發(fā)布版本是完全優(yōu)化的,需要禁用優(yōu)化以獲得最佳的調(diào)試效果

.NET Native 分析器。有一些 .NET Native 不支持的 .NET 功能,例如超過四維度以上的多維度矩陣(?。?。當(dāng)進(jìn)行 .NET Native 編譯時(shí)會(huì)了解到這些的。但是想要節(jié)約 .NET Native 編譯多出30+秒的時(shí)間,可以通過自行引用 Microsoft.NETNative.Analyzer(NuGet 包)立即得到警告。

AnyCPU被取消。這是因?yàn)?.NET Native 編譯為原生機(jī)器代碼。對(duì)于應(yīng)用程序開發(fā)而言,CPU 幾乎毫無份量。開發(fā)者僅需牢記在本地設(shè)備或者模擬器上部署時(shí)選擇 x86;在 Win10 移動(dòng)設(shè)備上部署選擇 ARM ;或者 x64(這并不比 x86 效果好)。當(dāng)為應(yīng)用商店開發(fā) Appx 包時(shí),該向?qū)?huì)生成三種不同的類型并提交到應(yīng)用商店。

如果正在開發(fā)一個(gè)類庫或 PCL,應(yīng)當(dāng)將其開發(fā)成「AnyCPU」類型。這將會(huì)使得事情簡單化——可單獨(dú)分配一個(gè)全部項(xiàng)目均可用的 DLL 文件。

我能找到的最簡單的方式就是:點(diǎn)擊 Build > ConfigurationManager 對(duì)話框。可以這樣設(shè)置,對(duì)于該庫而言,即使工具欄顯示「AnyCPU」,仍將 builds+deploys應(yīng)用為 x86 類型。

調(diào)試.NET Native。有時(shí),開發(fā)者想在 .NET Native 中設(shè)置斷點(diǎn)來調(diào)試代碼。但最好請(qǐng)不要在 Release 模式下這樣做,因?yàn)檎{(diào)試本身就很困難,.NET Native 的對(duì)代碼積極優(yōu)化將使得其難上加難。結(jié)果顯而易見,使用 Debug 模式(關(guān)閉優(yōu)化),然后臨時(shí)修改項(xiàng)目配置以便使用 .NET Native(即便是在 Debug 版本也要這樣做)。在 C# 中,在 .NET Native 工具欄中設(shè)置方式:Project > Properties > Compile。在 VB 中,設(shè)置方式:MyProject > Build > Advanced。

定制 .NET Native 優(yōu)化。尤其是在應(yīng)用程序中,通過巧妙地使用反射方式,.NET Native 可以刪除多余的優(yōu)化。這是可控的。這些博客解釋得很好:

  1. 靜態(tài)代碼中的動(dòng)態(tài)特性。
  2. 求助!我遇到 MissingMetadataException 異常。
  3. 求助!我沒遇到 MissingMetadataException 異常。
  4. .NET Native 深入探索:讓庫變得更好
  5. [.NET Native 深入探索:優(yōu)化運(yùn)行指令][1]。

Expression.Compile。之所以介紹它,是因?yàn)樗?Newtonsoft‘s Json.Net 內(nèi)部使用并且對(duì)開發(fā)者有著深遠(yuǎn)的影響。在傳統(tǒng)的 CLR 中,表達(dá)樹可在運(yùn)行時(shí)編譯為 MSIL,然后 JIT 將其轉(zhuǎn)為原生代碼。這在 .NET Native 中不會(huì)發(fā)生,.NET Native 將會(huì)解讀這些表達(dá)樹。請(qǐng)注意與 Json.Net 相比發(fā)生的變化,例如,啟動(dòng)時(shí)間縮短(無需加載 CLR 表達(dá)樹架構(gòu)),但在序列化大的數(shù)據(jù)文件時(shí)速度變慢。如果這對(duì)你的應(yīng)用較為重要,請(qǐng)親自測量。這一改變使得應(yīng)用程序啟動(dòng)時(shí)間縮短了200ms。

F#-- 任一 UWP 商店應(yīng)用程序均不能使用 F# DLLs:目前 .NET Native 不支持該文件。這是未來需要修復(fù)的一個(gè)問題。如果這對(duì)你很重要,請(qǐng)及時(shí)通知我們。

Get help。如果在使用 .NET Native 遇到問題,尋求解決方法的最好方式是發(fā)送電子郵件到 dotnetnative@microsoft.com。

總結(jié)

今天 Universal Windows Platform 發(fā)布為 .NET 開發(fā)者提供了一個(gè)全新的契機(jī)。對(duì) UWP 應(yīng)用而言,這是一筆巨大的財(cái)富,開發(fā)者可以使用最新的 .NET 技術(shù)開發(fā)應(yīng)用。

請(qǐng)大膽地做出嘗試并交流你的想法。如果存在任何問題。請(qǐng)?jiān)诖颂幓蛘咴赪indows Dev Center 的「Developing Universal Apps」論壇上留言。如果通過使用 .NET Native 優(yōu)化應(yīng)用程序的啟動(dòng)時(shí)間在200ms以下,請(qǐng)?jiān)谶@里大膽的炫耀吧!

OneAPM 助您輕松鎖定 .NET 應(yīng)用性能瓶頸,通過強(qiáng)大的 Trace 記錄逐層分析,直至鎖定行級(jí)問題代碼。以用戶角度展示系統(tǒng)響應(yīng)速度,以地域和瀏覽器維度統(tǒng)計(jì)用戶使用情況。想閱讀更多技術(shù)文章,請(qǐng)?jiān)L問 OneAPM 官方博客。
本文轉(zhuǎn)自 OneAPM 官方博客

原文鏈接:http://blogs.msdn.com/b/dotnet/archive/2015/07/30/universal-windows-apps-in-net.aspx

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容