歡迎光臨
每天分享高質量文章

.NET的前世今生與將來

來自:靈感之源

連結:http://www.cnblogs.com/unruledboy/p/net_past_present_future.html

前言


.NET正式誕生了16年了,目前是微軟技術棧的主要開發平臺。筆者有幸在2002年在生產環境使用.NET 1.0 beta,一直到現在.NET Core 2.1,見證了.NET從最開始蹣跚學步的嬰兒,到現在在各大領域大放異彩的巨人。

在過去的10多年中,開始那些年,.NET被質疑、誤解,一些開技術人員覺得.NET就是Java的複製品,沒有什麼值得學習和使用的,而且,一些反微軟陣營的技術人員,為了反對而反對。

正是由於這些偏見,至今,一些公司仍然不願意使用.NET,即便.NET從第一天開始就已經提交到ECMA標準和使用Rotor開放了程式碼和免費使用。

本文試圖給大家展示一個完整的.NET歷史、現狀、生態圈,希望在.NET擁抱開源界的時候,業界也能擁抱.NET,更多技術人員參與到.NET的大家庭中來。

現在,讓我們一起回顧一下.NET過去10多年的發展吧。

.NET技術棧


如果你想對.NET的整個技術棧有全面的理解和並希望深入研究,可以看筆者的爆棧下麵的.NET技術棧:http://overflowstack.github.io/

 

誤解

現在業界/一些開發人員對.NET這個平臺有諸多誤解,他們的想法可以概括如下:

  • .NET是封閉的


實際上,.NET從第一天開始便把標準提交到ECMA,並且利用Rotor 開放了原始碼(詳見這裡),感謝RednaxelaFX的指正

  • .NET只能在Windows平臺上跑


.NET 2004年開始就能在Linux上面跑了(Mono,詳見後面內容)

  • .NET帶來的費用高


.NET是開源的,可以在多平臺跑,沒有費用可言

  • .NET效能低


.NET(相關開發語言如C#)的效能在多個效能測試平臺上是領先的(詳見後面內容)

  • .NET是微軟的


這是典型的為了反而反,類似的幼稚行為是在微軟最近收購了GitHub後,一些開發人員馬上遷移到GitLab上,然而他們可能不知道:

  • GitLab是在微軟Azure託管的(不過他們最近遷移到Google Cloud了)

  • GItLab之前發生過因為主資料庫PostgreSQL備份/恢復出錯導致了客戶資料丟失的問題

 

前世


Windows 32


在2000年前,在微軟平臺上做開發,一般用的Windows 32 API,主要有以下幾種開發方案:

  • Visual C++

通用解決方案,可以是桌面應用(如MFC),也可以是C/S應用

  • Visual BASIC

快速應用開發(RAD)的一種,一般做圖形介面(GUI)應用

元件一般採用ActiveX(COM),利用登錄檔做介面管理

提醒:VB在.NET沒有缺席

  • Delphi

另外一種RAD,兼顧了VB的元件化和VC++的很好的底層API互動支援

Anders Hejlsberg是這個產品的首席架構師(提醒,他是.NET的核心人物之一,看下麵內容)

 

做Win 32開發,會面對一個問題:版本控制,因為介面改變了,但因為釋出管理不統一,導致了不同版本互相改寫,呼叫錯亂,這就是飽受詬病的.DLL地獄(Windows類庫一般用.DLL做字尾):

  • 標準Win32 DLL:要麼隨意放到Windows System32目錄,要麼Program Files (x86)目錄

  • ActiveX DLL:雖然統一用登錄檔做版本資訊管理,但是因為釋出的時候版本沒定義好,導致使用regsvr32.exe註冊的時候可能會把上一個版本改寫

 

做Web開發,當年微軟提供了ASP(Active Server Pages),使用VBScript做伺服器端指令碼,利用ActiveX做實際業務互動,譬如ADODB做資料庫儲存,但是這個解決方案在記憶體處理、安全方面都存在諸多問題。

 

前期


背景

誕生

微軟劍橋研究院的技術人員,在1998年開始研究下一代的開發技術,他們的思維很超前,去年他們發了一篇文章,介紹這個專案的發展史,上面的圖片,清晰可見一些.NET的特性,還有一些還沒有被實現。

.NET這個開發平臺,學習多個開發平臺的特性,譬如Java,把開發語言Java等(筆者註:別的Java平臺語言下麵提及)編譯成中間語言(IL),執行時JIT。不過.NET更進一步,支援本地化編譯。

2002年,微軟正式對外釋出了.NET 1.0。

最近,Oracle宣稱.NET的主要對手Java的安裝量超過20億,筆者還沒有找到.NET安裝量的官方數字。

.NET的名字


相信很多人會問,為什麼會取.NET這個名字?適逢當年2000-2002年網際網路大潮,微軟打算推出一個適應網際網路需求的開發平臺,所以乾脆用了.NET這個名字。當時很多公司開發的產品都加了.NET字尾,甚至公司域名都採用了.NET而不是.COM。

.NET特性

首先,.NET是一個開發平臺,從1.0開始支援GUI(WinForm)、CUI(控制檯)、Windows Service、Remoting等等Windows平臺的開發,也支援ASP.NET (WebForm)開發web系統,所以從最開始,.NET就支援多平臺開發。可以說.NET從第一天開始便是為了網際網路而生的。

.NET編譯生產的檔案叫程式集Assembly,就是程式碼物理的集合,名稱空間用來邏輯歸類程式碼。

語言 vs 平臺


有一些同學把語言和平臺搞混了,譬如他們會說.NET是一種語言。讓我們來捋一下關係吧:

  • 平臺:.NET

語言:C#,F#,VB.NET,等等

  • 平臺:JVM

語言:Java、Scala、Clojure,等等

 

有趣的是,現在流行的開發平臺大多採用了類似的編譯、執行、調優機制:

1、編譯成中間語言(IL)

2、執行時即使編譯成machine code(JIT,後述)

3、有辦法改變JIT的行為(調優)

4、有辦法預編譯成machine code

言歸正傳,.NET平臺上最主流的3種開發語言分別是C#、VB.NET和F#。

Pascal之父、Delphi首席架構師Anders Hejlsberg,當年還在Borland,被微軟CEO Bill Gates重金邀請加盟微軟,主導開發.NET平臺上的全新開發語言,這就有了現在.NET平臺上最流行的開發語言C# ,取義C++的++ ,即(C++)++,合在一起就是4個+,碰巧和音符的C♯一樣,所以讀作C sharp,不是C井,謝謝。

因為這個升C的字元比較難敲,所以,一般用數字3上面的那個#符合代替(對,♯和#不是同一個字元)。C#是目前全球最流行的開發語言之一。

如果你想深入瞭解C#,可以參考Jon Skeet編寫的《C# in depth》,JK很奇怪,他是在Stack Overflow上是排名第一的回答者,C#專家,然而,他卻是在Google工作的(潛伏的臥底?)。

筆者對BASIC有著非常深厚的感情,第一次接觸這個語言是1992/1993年的時候,後來用了GWBASIC、TrueBASIC、TurboBASIC、QBASIC、QuickBASIC、Visual BASIC (1.0版本還是DOS下的,用的ASCII字元拼接成圖形介面)。

如果你用Visual BASIC 5/6,相信不會對VB.NET太陌生,儘管VB.NET用起來有點彆扭。VB.NET錶面上是微軟照顧老VB使用者在.NET平臺上的實現,但這個語言實在太彆扭。在VB 11.0之前,它是儘量和C#高度互動的,很多語言特性都儘量“相容”,但是11.0之後,開發團隊決定和C#分道揚鑣,各自演進。

說起VB.NET,相信一些開發人員還記得@裝配腦袋,他從老VB開始就是忠實使用者,在部落格、技術會議中和大家分享各自VB.NET/編譯器技術和心得,他兩年前不幸因病去世,願天堂沒有bug。

VC++一直以開發高效能著稱程式,在.NET世界,VC++.NET,可以和.NET程式集互動,當然,你仍然可以選擇寫不基於.NET的程式碼。不過,如果你用,NET的話,為什麼不直接用C#?除了VC++.NET,微軟還有C++/CLI這個專門設計來和.NETA互動的相容C++的語言,用來開發.NET託管程式碼。

如果你需要高效能、喜歡函式式程式設計,那麼F#這個函式式的開發語言會比較適合你,它天生以高效能平行計算著稱。可能你還已經猜到,F#裡的F代表Functional函式式。

微軟當年雄心勃勃,希望把.NET打造為大一統的開發平臺,當年Java如日中天,微軟自然不會放過這個機會:難道還有直接把對手的支持者拉攏過來的而擴大市場更好的辦法嗎?此消彼長,道理大家都懂。

所以微軟推出了J#。不過這個專案有點尷尬,最開始是想和Java進行互動,利用Java成熟的平臺元件,後來專案沒有被維護了,但是,.NET 4.5之前,想要自己讀寫zip檔案,.NET框架內建的類庫中,只有J#有一個類庫,否則只能用第三方的方案。

J#出師未捷身先死,長使英雄淚滿襟。然而這並沒有阻止.NET的雄心。大家知道JVM是一個執行平臺,在這基礎上,有各種語言,Java是老大哥,Scala有取而代之的趨勢,最近Google因為不滿Oracle拿Java版權大棒亂揮舞,近年大力扶植JetBrains的Kotlin。同樣,.NET平臺上,也有多種語言,除了上述的幾種,還有Fantom、Visual COBOL、ClojureCLR等。

為了和動態語言互動,.NET引入了 Dynamic Language Runtime (DLR),這樣,各自動態語言就可以和.NET互相呼叫,而這個平臺下的語言一般有一個字首:Iron。

當年出現了IronPython、IronRuby、IronScheme等專案。然而,這個專案沒有被維護了。或許Iron是因為這個名字起得比較晦氣,都“打鐵”了。

核心特性


每種語言/開發平臺都有自己的看家本領:語言特性(面向物件 vs 函式式、強型別 vs 動態型別、平行計算等等)、生態圈(開放、大量的第三方庫/擴充套件支援)等等。

.NET的執行時Common Language Runtime(CLR)是.NET的核心,負責程式的解釋和執行。.NET程式啟動的時候,會經過多達50步才正式開始跑你寫的第一行程式碼,中間是各種元資料的查詢、分析等。

如果程式是第一次執行,CLR會把要執行的程式碼路徑進行JIT(即時編譯),這個過程會有各種最佳化,舉個例子:冷程式碼(如異常處理邏輯)會相對熱程式碼(正常邏輯)執行較慢,這就是為什麼如果過度使用異常來做控制,會有效能瓶頸。

如果你想對CLR進入深入的瞭解,可以參考傳奇開發人員Jeffrey Richter編寫的《CLR via C#》,他是經典開發書籍《Windows via C/C++ 》的作者。

.NET大量封裝Win 32 API,這叫InterOperability(InterOp)。如果你需要呼叫第三方甚至自己編寫的Windows 32,可以透過這個實現。

還記得DLL地獄嗎?.NET的程式集經過SN(強命名)簽名後,可以透過gacutil註冊到Global Assembly Cache(GAC),這樣任何一個程式可以直接呼叫。因為它透過程式集名稱(assembly name)來區分每個程式集的唯一性,所以不會出現不同版本的程式集互相改寫的問題。

C/C++,沒有第三方的庫,你需要手工控制記憶體的呼叫和回收,好處是按需呼叫,省記憶體,高效,然而對開發人員有較高要求,所以一般使用第三方的解決方案。

Java和.NET,都有自己的Garbage Collection (GC)。

.NET GC分3個階段,不同階段針對物件的不同生命週期。

如果你希望深入研究GC,可以參考下麵的”高效能”部分。

不同於現在各種基於Google Chromium二次打包的瀏覽器殼,除了完整版,.NET還包括多個不同的兄弟框架,譬如.NET Execution Environment (DNX)、Compact Framework (CF)用於移動裝置、Microsoft Framework (MF)用於嵌入式裝置。

開發


Visual Studio是最受微軟技術開發人員歡迎的IDE,你可以透過它使用上述各種語言開發、除錯、測試、釋出各種應用。或許你不知道,Visual Studio作為通用的IDE,被其它產品借用,譬如微軟SQL Server的管理工具SQL Server Management Studio (SSMS)就是基於Visual Studio的,所以大部分快捷鍵和功能是一致的。

剛開始的時候微軟推出的.NET針對自家Windows桌面開發推出了Windows Form(WinForm)這個開發方案。出發點是想把所有介面元素OO化,透過事件驅動,底層還是Win32那套訊息機制,GDI+渲染。不過預設的渲染效果有審美疲勞,所以有些應用採用了國內比較流行的面板做法,透過owner draw實現自主的渲染,擺脫了單一的UX體驗。

不喜歡WinForm的事件模型?不喜歡自己實現雙向系結?不喜歡WinForm太傳統的Win32 GUI元素?那麼,WPF應該會是你的選擇。它使用XAML作為介面語言,DirectX渲染,邏輯程式碼可以選擇C#或者VB.NET。之所以使用XAML(XML格式),是為了把介面描述標準化,這是iOS、Android和Xamarin的標準做法。

.NET的推出是為了應對網際網路時代,必不可少的,需要提供網站開發方案。微軟把當年的基於ActiveX + VBScript的伺服器端開發解決方案ASP(Active Server Pages)升級,成為了ASP.NET。WebForm的設計思想是複製WinForm,但是封裝得不好,導致用戶被迫強行做各種js和css hack,尤其是它複製WinForm的事件模型,導致各自不必要的Postback,而且頁面有著極其臃腫的ViewState來維護當前的狀態,所以很多時候頁面載入耗時甚長,久等不見內容。當然你可以用UpdatePanel做非同步ajax更新提升使用者體驗。

WebForm設計缺陷包括但不僅限於:

  • 早年的封裝沒有考慮各個瀏覽器的相容性,開發者必須做各種js/css hack

  • 表格postback設計導致不理想的使用者體驗

  • 使用ViewState做當前頁面的狀態保持,但這個ViewState是寫入到頁面的,預設是寫入到檔案前面部分,但頁面資料量多的時候(如使用DataGrid),這個ViewState會相當大,導致頁面載入緩慢,雖然有辦法把ViewState放到頁面後面部分,讓載入看起來快點,但是根本問題沒有解決。而且ViewState會出現各種損壞的情況導致功能無法使用

  • 容易導致開發人員把介面、業務邏輯和資料儲存都放到同一個檔案裡面,難以維護和做單元測試

  • 慢,慢,慢,重要的事情要說三遍

 

為瞭解決在飽受詬病的WebForm中出現的各種問題,微軟推出了ASP.NET MVC,這是對當年市場上日漸流行的Web設計方式Model View Controller的回應,這個產品後來開源了。ASP.NET MVC的設計思想是好的,把介面、業務邏輯、資料模型等分離,這樣不同角色的人員可以獨立進行開發,互不幹擾。

 

ASP.NET MVC自帶幾種渲染器:

  • ASP.NET WebPages就是ASPNET WebForm (不要用)

  • ASP.NET Razor 就是.cshtml/.vbhtml檔案的渲染器 (還是不要用)

你可能會問,那到底用什麼做頁面渲染?簡單來說:不要在伺服器端做渲染,因為所有介面渲染都不應該是伺服器的事情,現在使用者的瀏覽器渲染能力很強,這種事情完全應該留給客戶的機器去做,這樣伺服器的壓力會大減。

伺服器應該做的事情只是接受請求,根據業務邏輯處理資料、讀取/儲存資料。

所以,頁面渲染,應該選擇成熟Web前端MVC方案,譬如AngularJS、React等。

網路開發,除了網站,還有一些不可見的後臺服務。Web Services是跟隨ASP.NET 1.0推出的,協議基於XML,現在使用這個技術的產品比較少了。

後來微軟推出了大一統的WCF(Windows Communication Foundation)平臺,是相對較新的一套Web服務解決方案,支援多種傳輸協議和安全機制,但配置繁瑣。

ASP.NET Web API是ASP.NET MVC的一個元件,提供構建RESTful API的方案,目前比較多產品使用。

大家還記得Java Applet嗎?當年Flash大行其道,但其問題太多,安全問題、CPU佔用問題、穩定性等等。

為了對抗如日中天的Flash,微軟推出了Silverlight。Silverlight的效能不亞於Flash,而且比隔三差五要打安全補丁的Flash安全很多,但是兩者都無法擺脫基於ActiveX外掛的問題,即便預先安裝,也常有版本相容問題導致無法在瀏覽器載入,而且預設那套銀灰色的介面確實有審美問題。

Silverlight的著名的應用:

  • 當年奧運會MSNBC的網路直播採用Silverlight解決方案

  • 微軟的本地虛擬機器管理平臺Windows Controller,用的就是Silverlight

  • 微軟雲平臺Azure,早期版本,使用了Silverlight做介面

 

不過和Flash抵擋不了技術發展的洪流一樣,Silverlight也被迫退出了市場。對了,Flash在中國還是奇葩地存在,由某個流氓公司特供中國版,切記不要使用。

一個成熟的開發平臺,單純有好的語言、基礎庫還是不足夠的。當年為了方便開發人員,微軟提供了一整套的常用功能框架,叫Enterprise Library,包括功能如讀寫配置、資料訪問、日誌、快取等,而這個專案的前身是Best Practice Application Blocks,就是類似廣大開發愛好者常常自己搞的工具庫。

大家還記得ActiveX年代的ADODB嗎?在.NET世界,我們有升級版:ADO.NET。透過ADO.NET,你可以訪問各大資料庫系統。大部分資料庫系統是支援多執行緒的,所以需要讀寫資料的時候:

  • 當你單執行緒讀寫資料的時候,已經用了command.Prepare(),甚至在允許表鎖定的情況下用了connection.BeginTransaction()還是覺得慢,那麼,

  • 可以用多執行緒,這裡可以Parallel下的方法,一般多執行緒下會快帶來幾倍的效能提升,如果你還是覺得慢,那麼,

  • 使用bulk copy。一般大型資料庫系統都提供這個,譬如SQL Server提供SqlBulkCopy(本質上是BULK INSERT),譬如PostgreSQL提供的COPY命令

 

隨著技術的發展,面向物件進入資料儲存和訪問領域。譬如資料訪問,這些解決方案叫O/RM,物件關係對映。

在Java領域著名的Hibernate被移植到.NET成了NHibernate,Dapper也是一個不錯的輕量級的選擇。微軟也推出了自己的Entity Framework,後來並開源了。

不過不管是Code First、Model  First還是Database First,這些OO化的O/RM,因為物件化這個過程,效能損耗不可避免,而且,不同的解決方案要麼解決不了延遲載入,要麼做不好快取,或者動態生成的SQL效率低下。

如果你需要絕對的高效能,還是應該手工寫SQL,並且封裝到儲存過程,這樣業務邏輯不需要在每次執行的時候都在客戶端/伺服器不斷傳輸。想象一下,即便某業務邏輯執行速度很快,但數量巨大,譬如一天100萬次,當這個業務邏輯很複雜,譬如100K,那麼一天光是這些SQL的網路流量起碼是100GB,如果如果是封裝成SP,那麼,可能就是100MB。

同時,使用這些O/RM,一般會遇到對具體某種RDBMS的特性支援不好的情況,需要使用底層SQL直接呼叫操作,這樣O/RM就無法直接切換到別的資料庫系統了。

NoSQL蓬勃發展,在傳統關係型資料庫系統中被常規化的資料(一條資料會被儲存到不同的欄位甚至不同的表),現在作為一個json檔案(字串)被儲存到各種型別的NoSQL中。

NoSQL優勢是快速的讀寫,因為避免了多表關聯的可能,一次讀取,一次寫入。但是真因為這樣,絕大部分NoSQL無法做跨表(集合)的關聯,因此一般的做法是用定時任務生成標的資料,這種解決方案有2個問題:資料非實時和冗餘的空間佔用,同時,json檔案本身的所有屬性是鍵值對,所以空間佔用遠遜於RDBMS。

市面上不乏基於.NET的NoSQL,部分還是開源的,筆者覺得最好的一個是開源的STSDb,獨創的Waterfall索引比傳統的b+樹要跟高效能。

大量業務系統都需要用到工作流。WF(Windows Workflow)是微軟額外推出的基於.NET的工作流系統,不過這個方案配置起來有點羅嗦。

生態圈

 

從別的成熟平臺中移植著名的專案是業界慣常的做法。一些著名/優秀的專案被移植到.NET,譬如Java世界的hibernate (nhibernate)、junit (nunit)、iText  (iTextSharp)、Quartz (Quartz.net)、Lucence (Lucence.net)、Log4j (log4net)。

一個開放平臺的成熟,離不開社群的支援。開源/程式碼託管網站,早期的有SourceForge.net、CodeProject等,後來微軟自己推出了自己的GotDotNet,後來變成了CodePlex.com,然而幾個月前這個專案已經停止運轉,大部分專案都被作者各自遷移到GitHub。

.NET框架和C#從第一天開始,就作為ECMA標準公開了原始碼,這為後來的Mono和跨平臺打下了堅實的基礎。幾年前,微軟把.NET完全開源了,包括編譯器、框架、類庫等等。

著名的Linux GUI解決方案GNOME之父Miguel de Icaza,建立了Mono專案,讓.NET真正跨平臺,在Linux、MacOS下執行。

Mono專案同時帶來了SharpDevelop這個IDE,後來又被移植到別的平臺上成為了MonoDevelop。

Mono專案近年被Ubuntu擁抱,跟隨標準釋出預裝。

今生


.NET的發展腳步沒有停下來,它不斷進化,現在,.NET已經在各大平臺紮根。

最近的15年週年紀念活動,Anders Hejlsberg被Channel 9邀請參與活動,並講述了他對C#的看法,他表示:“我也沒想到C#能如此興盛。”

如果說.NET平臺是心臟,那麼,語言就是骨絡。目前.NET平臺上3大主流開發語言有各自的演進路線。

C#作為先鋒在新特性上不斷快速進化,譬如LINQ/Lambda、async/await平行計算等,當然動態特性也是值得提及的。如果一個東西走起來像鴨子,叫起來像鴨子,它可能不是一隻鴨子而是被鴨子帶壞了的鸚鵡。

如果你想知道C#的各種技術內幕,可以看Matt Warren的技術部落格,他是C#語言委員會的成員之一,這個委員會決定每個版本的新特性。

Roslyn作為新一代的編譯工具,使用C#編寫,終於實現了.NET的自舉,這是一個語言成熟的標誌。

開發工具


不僅僅是各種語言跨平臺,微軟的開發工具也能跨平臺。Windows上最佳開發IDE Visual Studio現在不僅僅在Windows上跑,微軟推出的兄弟Visual Studio Code還支援Linux和MacOS,還有Visual Studio For Mac。

相信做過開發的同學都對各種第三方依賴元件的引入、維護都很煩惱,NPM、webpack、Chocolatey、Maven Repository等都是著名的包管理解決方案,微軟效仿之,推出了NuGet。

本質上NuGet包和Office系列的檔案類似,都是zip檔案,裡面有一些元資訊和實際檔案。透過Visual Studio的專案Package選單你可以直接生成NuGet包。早期的NuGet不允許直接下載包,非常惱人,必須透過客戶端如Visual Studio,現在允許了。

如果你想架設自己的NuGet包管理平臺,可以使用ProGet。

案例


或許你會想,.NET到底有什麼優秀的案例?

如果你做Web開發,相信你聽過甚至用過OWIN專案,它包括了SignalR、Nancy、Katana等專案。如果你用過IoC,你應該聽過甚至用過Windsor,它是Castle專案的一員,包括了ActiveRecord、MonoRail等。相信你用過stackoverflow?它以及眾多兄弟網站,都屬於StackExchange,而這些所有網站都是基於ASP.NET的。微軟自家一些產品也是完全或者部分使用.NET實現的,譬如BizTalk、Blend等。

如果你想瞭解更多的優秀.NET解決方案,可以看這個非常詳細的串列:https://github.com/Microsoft/dotnet/blob/master/dotnet-developer-projects.md

瞭解或者開發過雲應用嗎?業界領先的公有雲提供商微軟Azure,這個平臺大部分技術都是基於.NET的。對了,Bing搜尋引擎也是。

Unity是流行的2D/3D遊戲開發平臺,其腳本系統主要是Mono,它剛剛對外宣佈支援最新版版本Mono。另外一個遊戲引擎Godot,也是使用Mono作為指令碼引擎。

有些技術牛人,利用.NET打造自己的開源的作業系統。

譬如比較早期的Cosmos OS ( https://www.gocosmos.org/ ),還有近期的FlingOS( http://www.flingos.co.uk/ )。

由此可見.NET作為一個開發平臺的能力和潛力。

為了實現跨CPU平臺(x86和ARM等),微軟為 Windows帶來了UWP,開發者可以使用多種開發語言(.NET家族的,甚至HTML/WinJS)開發Windows平臺應用,介面語言是XAML,這些應用不僅僅可以在Intel的x86平臺下跑,還可以在ARM上跑。大家還記得Windows Phone和Surface嗎?

跨平臺


之前說過Mono這個跨平臺開發解決方案,在支援Linux/MacOS的基礎上,它繼續進化,衍生出Xamarin專案,實現了對主流手機系統蘋果iOS、Google Android、微軟WP甚至三星Tizen的支援。

2016年微軟收購了Xamarin,整合到Visual Studio裡,並且將其開源,創始人Miguel de Icaza成為微軟的Distinguished Engineer。

DotNet Anywhere (DNA)是另外一套跨平臺解決方案:https://github.com/chrisdunelm/DotNetAnywhere

2016年,微軟為了大一統.NET平臺標準,推出了.NET Standard,可以把這個看成一個協議,而不是具體實現。具體實現是.NET完整版 4.x、.NET Core 2.x、Xamarin等。

.NET完整版4.x現在統治Windows平臺,Xamarin複製移動平臺,而.NET Core則主打跨平臺,如Linux、MacOS、Docker、嵌入式裝置、IoT等,譬如已經有Raspberry Pi等裝置在執行.NET Core。或許你不知道,Docker For Windows是用.NET編寫的。

.NET Core做法和.NET完整版在API層面基本上一直和相容,區別在於,.NET完整版是依賴本地GAC安裝/本地目錄的.NET程式集,而.NET Core是依賴NuGet包,所有基礎類庫都是NuGet包,而這些包不像老版本的node.js那樣都安裝到本地目錄,而是集中安裝到本機的NuGet庫裡。

和.NET Core匹配的有ASP.NET Core,允許開發人員開發在Linux等平臺跑的Web系統。

.NET開發初期,大量借鑒Java這個平臺的優點,近年,Java作為平臺和作為語言,分別複製了,NET和C#的一些特性。JavaScript的一些新特性直接複製了C#的特性。

高效能


業界做效能測試的時候,一般會用這句話:“不服跑個分!”。網上有各種效能評測文章/比較網站,最近看過一個完整,各種語言互相比較,其中.NET和Java的結果差異不大,11個比較專案中,.NET 6 : 5 Java。

.NET為了提高效能,透過如下幾個不同狀態下方式:

  • 語言:支援Parallel等平行計算

  • 編譯:編譯器會做各種最佳化,譬如程式碼行內,像常量和列舉等,會直接把實際值複製到呼叫方

  • JIT:除了根據程式碼訪問路徑進行動態即使編譯之外,還可以使用更可控的Profile Guided JIT

  • 本地化:可以使用多種方式進行本地化編譯,譬如ngen命令列和C# Native

  • LLVM:有一個開源專案,叫SharpLang,使用LLVM作為基礎對C#程式碼進行編譯。R大指出還有 https://github.com/dotnet/llilc 這個專案

 

以上是語言/框架層面的最佳化,如果做了上述的事情後仍然對效能不滿意,那麼你可以:

  • 最佳化演演算法,有可能帶來數十倍的效能提升

  • 重構設計和實現,原來的設計可能是錯的,也可能是現在有更好的解決辦法,重構/重新實現可以改善效能

  • .NET執行時的調優

如果你使用多執行緒(包括Parallel),那麼你可以修改一下ThreadPool的MinThreads數量

如果你呼叫HttpClient/HttpWebRequest等網路方法,那麼,你可以修改一下ServicePointManager的DefaultConcurrentConnectionLimit,因為微軟為了遵循古老的HTTP規則,對同一個網站最多隻允許2個併發連線

修改GC為Server樣式

 

如果你還需要更高效的解決方案,可以考慮Map Reduce分散式計算,所謂的分而治之

如果你想深入研究如何編寫高效能的.NET程式,可以參考Ben Watson編寫的《Writing High-Performance .NET Code》這本書。

如果你還是不滿足於效能表現,可以使用GPU加速,目前比較成熟的解決方案是AleaGPU,對C#的支援非常友好。

將來


Web前端開發技術日新月異,但同時也存在各種髒亂差的情況(筆者會另外撰文詳細述說)。

近來各大瀏覽器加入了對Web Assembly的支援,Web Assembly允許開發人員用如C++等語言實現邏輯,然後編譯成二進位制的Web Assembly。

最近,微軟宣佈ASP.NET專案引入了Blazor專案(取義Browser + Razor),這個專案是基於DotNet Anywhere的,允許開發人員用.NET + Razor實現前端功能。

在Windows平臺上(x86和ARM),你可以使用.NET設計UWP應用,但其它平臺上,你不能用.NET做帶介面的應用。

最近對外公佈的AvaloniaUI,允許大家使用UWP類似的技術在Linux和MacOS上實現桌面應用,這個專案的名字看出來和當年的Avalon專案的關係了嗎?

現在技術界喜歡搞cross play,譬如Windows 10下自帶了Linux子系統,SQL Server也可以在Linux上跑,JavaScript可以透過node.js寫伺服器端程式碼,.NET也可以寫Web Assembly做前端。

.NET發展16年,為業界帶來各種新技術的同時,也給人類的發展做出了重大貢獻,它會繼續和老對手Java等一起齊頭併進,互相追趕和促進。

謹以此文紀念我敬重於於2016年9月17日去世的 裝配腦袋 逝世兩週年。

 

如果你看到這裡,那告訴你一個訊息:世界那麼大,我想去看看。再次上路,去追求心中的理想。

 

爆棧網


爆棧網Kayow.com融合了我10多年來的經驗、心得、吸取的教訓,頻繁地發表高質量的技術文章: http://kayow.com


●編號145,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

Web開發

更多推薦18個技術類公眾微信

涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

贊(0)

分享創造快樂