欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    伴隨Windows 10推出的EDGE網(wǎng)頁瀏覽器,并沒有如微軟所愿,成為繼IE之后的流行網(wǎng)頁瀏覽器,當中不不成功的原因很多,但“難用”會是非常大的原因,所以在一臺全新Windows系統(tǒng)的電腦上,EDGE不過是大家用來下載另外一個瀏覽器的工具(如果你保留有安裝包,甚至不用打開它),所以微軟,他們在2018年底確認將會更換EDGE的內(nèi)核為Chromium,在經(jīng)過漫長的一年beta后,現(xiàn)在新內(nèi)核的EDGE已經(jīng)正式上線了。

    在此前的EDGE瀏覽器中,微軟采用了自研的EdgeHTML渲染引擎,其實在性能上是要領(lǐng)先Chromium內(nèi)核的,但如今HTML、JavaScript和CCS語言對Chromium內(nèi)核支持更好,所以EDGE在打開主流網(wǎng)頁時的實際表現(xiàn)不如Chromium內(nèi)核的瀏覽器,這是用戶所詬病的地方,所以無奈之下,微軟也只能選擇換用Google這個開源的網(wǎng)頁渲染內(nèi)核。

    這個新版的EDGE瀏覽器除了更換新內(nèi)核,其它部分是與原來EDGE瀏覽器差不多的,包括UI界面、與Windows 10的優(yōu)化支持、微軟賬號的云同步等等功能都有保留,而且微軟還為新瀏覽器做了個新logo,采用漸變顏色的立體設(shè)計,這與原來的扁平化風格截然不同,據(jù)說新logo其實是個浪花的,也就是大家俗稱“上網(wǎng)沖浪”的意思在里面。

    目前微軟提供了Windows 10/8/8.1/7、macOS、Andorid和iOS多個平臺的EDGE瀏覽器提供下載安裝,你可以點這里獲取,但如果你不手動安裝的話,在未來Windows 10系統(tǒng)更新時也是會把現(xiàn)有EDGE陸續(xù)自動更新到這個版本,另外微軟還為UWP平臺的EDGE提供了ARM64版本的beta測試,這個需要快速通道的測試用戶才能收到。

    我們很高興今天.NET5.0正式發(fā)布。這是一個重要的版本—其中也包括了C# 9和F# 5大量新特性和優(yōu)秀的改進。微軟和其他公司的團隊已經(jīng)在生產(chǎn)和性能測試環(huán)境中開始使用了。這些團隊向我們反饋的結(jié)果比較令人滿意,它證明了對性能提升及降低Web應用托管成本的機會有積極的表現(xiàn)。從預覽版1開始,我們一直在5.0上運行我們自己的網(wǎng)站。從我們目前的所見所聞來看,.NET5.0無需在升級上花費太多的精力就能帶來巨大的價值。對于你的下一個應用來說,這是一個很好的選擇,而且可以直接從早期的.NET Core版本升級。我們希望您在臺式機、筆記本電腦和云實例上正式開始使用它。

    ASP.NET Core、EF Core、C#9和F#5也將在今天一同發(fā)布
    您可以下載.NET5.0,適用于Windows、MacOS和Linux,適用于x86、x64、Arm32和Arm64。

    • l 安裝程序和二進制文件
    • l Docker 容器 images
    • l Linux package
    • l 發(fā)行說明文檔
    • l 已知的問題
    • l GitHub問題跟蹤器
    • l .NET 5.0貢獻者

    對于Visual Studio用戶,您需要Visual Studio 16.8或更高的版本才能在Windows上使用.NET 5.0,在MacOS上使用最新版本的Visual Studio for Mac)。Visual Studio Code的C#擴展也已經(jīng)支持.NET5.0和C#9。

    NET 5.0是我們的.NET統(tǒng)一之旅的第一個版本。我們構(gòu)建.NET 5.0是為了讓更多的開發(fā)人員能夠?qū)⑺麄兊?NET Framework代碼和應用程序遷移到.NET5.0。我們在5.0中也做了很多前期工作,以便Xamarin開發(fā)人員在發(fā)布.NET6.0時可以使用統(tǒng)一的.NET平臺。在后面的文章中會有更多關(guān)于.NET統(tǒng)一的內(nèi)容。

    這個版本是完全開源的第五個主要的.NET版本。現(xiàn)在,在GitHub上的DotNet org中,有大量的個人和公司(包括.NET Foundation企業(yè)贊助商)作為一個大型社區(qū)在.NET的各個方面共同工作,.NET5.0中的改進是許多人通過他們的努力及創(chuàng)新的想法構(gòu)成的結(jié)果,所有這些都超出了微軟對該項目的管理。為此,我們向所有為.NET 5.0(以及之前的版本)做出貢獻的人表示 “萬分感謝”!
    我們早在2019年5月就引入了.NET5.0,當時甚至設(shè)定了2020年11月的發(fā)布日期,結(jié)果我們?nèi)缙诎l(fā)布了,為此要感謝團隊中的每一個人,是他們讓這一切成為現(xiàn)實! 2021年11月我們還將發(fā)布.NET 6.0,今后每年的11月我們都將發(fā)布新的.NET版本。

    .NET 5.0亮點

    在.NET5.0中有許多重要的改進:

    l .NET5.0已經(jīng)在dot.net和Bing.com上托管了幾個月,已經(jīng)經(jīng)過了數(shù)個月的實際測試。

    l 許多組件的性能都得到了極大的提高,在.NET5.0中的性能改進、.NET5.0中的ARM64性能和GRPC中都有詳細描述。

    l C#9和F#5提供了新的語言改進,比如C# 9的頂級程序和記錄,而F# 5提供了交互式編程,.NET上函數(shù)式編程的性能得到了提升。

    l .NET庫增強了Json序列化、正則表達式和HTTP(HTTP 1.1、HTTP/2)的性能。

    l 改進了GC、分層編譯和其他方面,P95延遲有所降低。

    l 通過ClickOnce客戶端發(fā)布應用程序,單文件應用程序,減小的容器映像大小以及添加的Server Core容器映像,應用程序部署選項更好。

    l Windows Arm64和WebAssembly擴展了平臺范圍。

    我已經(jīng)為.NET5.0寫了很多Demo。您可以看一下這些.NET5.0示例,以了解更多關(guān)于新的C#9和庫特性的信息。
    平臺和Microsoft支持

    對于Windows、MacOS和Linux,.Net 5.0的平臺支持列表與.NET Core 3.1幾乎相同。如果您在受支持的操作系統(tǒng)上使用.NET Core 3.1,則應該能夠在該操作系統(tǒng)的大部分版本上采用.NET 5.0。在.NET 5.0中,最重要的新增功能是Windows Arm64。

    .Net 5.0是當前版本。這意味著它將在.NET6.0發(fā)布后的三個月內(nèi)得到支持。因此,我們預計到2022年2月中旬將支持.NET5.0。與.NET Core 3.1一樣,.NET6.0將是一個LTS版本,并將支持三年。
    平臺統(tǒng)一的愿景

    去年,我們分享了一個統(tǒng)一的.NET生態(tài)系統(tǒng)的愿景。它對您的價值在于,您將能夠使用同一組API、語言和工具來覆蓋廣泛的應用類型,其中包括移動、云、桌面和物聯(lián)網(wǎng)。您可能已經(jīng)意識到,現(xiàn)在您已經(jīng)可以使用.NET面向廣泛的平臺,但可能工具和API在Web和Mobile之間并不總是相同的,或者并不總是同時發(fā)布的。
    作為.NET5.0和6.0的一部分,我們正在將.NET的產(chǎn)品體驗盡可能的進行統(tǒng)一,同時使您能夠選擇您想要使用的.NET平臺的部分。如果你想以Mobile而不是WebAssembly為目標,你不需要下載WebAssembly工具,反之亦然。ASP.NET Core和WPF也是如此。您還可以通過更簡單的方式從命令行獲取所需的所有.NET工具以及構(gòu)建和運行時包。我們正在為.NET平臺組件提供包管理器體驗(包括使用現(xiàn)有的包管理器)。這對于很多場景來說都是很棒的。快速構(gòu)建開發(fā)環(huán)境和CI / CD可能是最大的受益者。
    實現(xiàn)這一愿景的第一步是整合.NET repos,包括Mono的一個大子集。擁有一個用于運行時和.NET庫的repo是在任何地方交付相同產(chǎn)品的前提條件。它還有助于進行廣泛的更改,這些更改會影響運行時和庫,而這些庫以前是有repo邊界的。一些人擔心,大規(guī)模回購將更難管理。事實證明并非如此。

    在.NET 5.0版本中,Blazor是利用回購整合和.NET統(tǒng)一的最佳例子。Blazor WebAssembly的運行時和庫現(xiàn)在是從合并的 DotNet/runtime repo所構(gòu)建的。例如,這意味著服務(wù)器上的Blazor WebAssembly和Blazor對List<T> 將使用完全相同的代碼。但在.NET5.0之前,Blazor并非如此。我們對Blazor WebAssembly采取的方法與我們在.NET6.0中使用Xamarin的方法非常相似。

    .NET Framework仍然是受支持的Microsoft產(chǎn)品,并且每個新版本的Windows都將繼續(xù)支持它。我們?nèi)ツ晷家呀?jīng)停止向.NET Framework添加新功能,并完成了向.NET Core添加.NET Framework API。這意味著現(xiàn)在是考慮將您的.NET Framework應用程序遷移到.NET Core的好機會。對于.NET Framework客戶端開發(fā)人員,.NET5.0支持Windows窗體和WPF。我們從許多開發(fā)人員那里聽說,從.NET Framework移植非常簡單。對于.NET Framework服務(wù)器開發(fā)人員,您需要采用ASP.NET Core才能使用.NET 5.0。對于Web Forms開發(fā)人員,我們相信Blazor通過更高效、更現(xiàn)代化的實現(xiàn)提供了類似的開發(fā)體驗。WCF服務(wù)器和工作流用戶可以查看支持這些框架的社區(qū)項目。從.NET Framework移植到.NET Core文檔是一個很好的起點。這就是說,如果你對自己的體驗滿意,那么讓你的應用程序運行在.NET Framework上是一個很好的方法。

    Windows團隊正致力于研究Reunion作為UWP及其相關(guān)技術(shù)的下一步。我們一直在與Reunion團隊合作,以確保.NET5.0及更高版本能夠很好地與WinUI和WebView2協(xié)同工作。

    讓我們來看看5.0版本中的新特性。

    語言

    C#9和F#5是.NET5.0版本的一部分,包含在.NET5.0 SDK中。Visual Basic也包含在5.0 SDK中。它不包括語言更改,但進行了改進以支持.NET Core上的Visual Basic應用程序框架。
    C#源代碼生成器是一項重要的C#編譯器新特性。從技術(shù)上講,它們不是C#9的一部分,因為它沒有任何語言語法。請參閱新的C#源代碼生成器示例,幫助您開始使用這一新功能。我們希望在.NET6.0及更高版本的.NET產(chǎn)品中更多地使用源代碼生成器。
    為了親身試用新版本,我們部分人決定更新DotNet/iot Repo,以使用新的C#9語法并以.NET5.0嘗試目標。它使用頂級程序、記錄、模式和切換表達式。它也已更新,以利用.NET庫中完整的可為空的注釋集。我們還更新了.NET物聯(lián)網(wǎng)的文檔。我們將查看該repo中的幾個示例來探索C#9。

    LED-BLINK程序是一個不錯的緊湊高級程序示例

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    using System;

    using System.Device.Gpio;

    using System.Threading;

    var pin=18;

    var lightTime=1000;

    var dimTime=200;

    Console.WriteLine($"Let's blink an LED!");

    using GpioController controller=new ();

    controller.OpenPin(pin, PinMode.Output);

    Console.WriteLine($"GPIO pin enabled for use: {pin}");

    // turn LED on and off

    while (true)

    {

    Console.WriteLine($"Light for {lightTime}ms");

    controller.Write(pin, PinValue.High);

    Thread.Sleep(lightTime);

    Console.WriteLine($"Dim for {dimTime}ms");

    controller.Write(pin, PinValue.Low);

    Thread.Sleep(dimTime);

    }

    您可以看到target-typed的使用以及new對controller變量的分配。。GpioController類型僅在賦值的左側(cè)定義。類型是在右手邊推斷出來的。這種新語法是var的另一種選擇,var的類型只顯示在賦值的右側(cè),并通過關(guān)鍵字var在左側(cè)推斷。
    通過定義方法并利用在相同或其他文件中定義的類型,頂級程序也可能增加復雜性。CharacterLcd示例演示了其中一些功能。
    邏輯和屬性模式

    C# 9包括對新模型的支持。您可以在如下代碼中看到關(guān)于這個邏輯模式的示例。

    1

    2

    3

    4

    5

    6

    var threshChoice=Console.ReadKey();

    Console.WriteLine();

    if (threshChoice.KeyChar is 'Y' or 'y')

    {

    TestThresholdAndInterrupt(ccs811);

    }

    另一種新模式是屬性模式。您可以在我的Mycroft信息訪問6.0示例中看到幾個屬性檢查。以下代碼摘自PN532 RFID和NFC讀取器示例。

    1

    2

    3

    4

    if (pollingType is not { Length: <=15 })

    {

    return null;

    }

    此代碼測試pollingType(類型為byte[]?)。為空或包含>15個字節(jié)。這是返回NULL之前需要測試的兩個錯誤條件。也可以將此測試編寫為pollingType為空或{Length:>15}。
    我想再給你看兩個模型。第一個是Mcp25xxx CAN總線的邏輯模式。

    1

    2

    3

    4

    5

    6

    public static byte GetRxBufferNumber(Address address)=> address switch

    {

    >=Address.RxB0D0 and <=Address.RxB0D7=> 0,

    >=Address.RxB1D0 and <=Address.RxB1D7=> 1,

    _=> throw new ArgumentException(nameof(address), $"Invalid address value {address}."),

    };

    第二個是Piezo蜂鳴器控制器中的邏輯模式。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    if (element is not NoteElement noteElement)

    {

    // In case it's a pause element we have only just wait desired time.

    Thread.Sleep(durationInMilliseconds);

    }

    else

    {

    // In case it's a note element we play it.

    var frequency=GetFrequency(noteElement.Note, noteElement.Octave);

    _buzzer.PlayTone(frequency, (int)(durationInMilliseconds * 0.7));

    Thread.Sleep((int)(durationInMilliseconds * 0.3));

    }

    記錄

    C#9包括一個名為Record的新類。與常規(guī)類相比,它有許多優(yōu)點,其中一半與更簡潔的語法有關(guān)。以下記錄取自Bh1745 RGB傳感器綁定。

    1

    public record ChannelCompensationMultipliers(double Red, double Green, double Blue, double Clear);

    然后在同一文件中稍晚一點使用它,語法很熟悉:

    1

    ChannelCompensationMultipliers=new (2.2, 1.0, 1.8, 10.0);

    可為空性注釋的改進

    現(xiàn)在,.NET庫完全為空性添加了注釋。這意味著如果您啟用nullability,您將從平臺獲得更多類型信息來指導您使用該功能。目前,還沒有對.NET文檔進行完整的注釋。例如,String.IsNullOrEmpty(String)應該被注釋為接受一個字符串?,而String.Split(Char[])的注釋是char[]?我們希望這個問題很快就能解決。完整的信息可以在Soure.dot.net上找到,也可以通過Visual Studio中的F12元數(shù)據(jù)查找獲得。

    System.Device.Gpio和Iot.Device.Bindings包(這兩個包的版本都是1.1.0)也作為此版本的一部分進行了注釋,使用了更新的.NET5.0注釋。這兩個庫都是多目標的,但是,我們使用5.0視圖為所有目標生成注釋。

    我們還添加了新的注釋類型。大型類在從構(gòu)造函數(shù)調(diào)用的幫助器方法中實例化對象成員是很常見的。C#編譯器不能遵循對對象賦值的調(diào)用流程。當退出構(gòu)造函數(shù)時,它會認為該成員為空,并將使用CS8618發(fā)出警告。MemberNotNull屬性可以解決此問題。將該屬性應用于幫助器方法。然后,編譯器將看到您設(shè)置了此值,并意識到該方法是從構(gòu)造函數(shù)調(diào)用的。MemberNotNullWhen類似。

    您可以使用以下代碼在BMxx80溫度傳感器中看到MemberNotNull的示例。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    [MemberNotNull(nameof(_calibrationData))]

    private void ReadCalibrationData()

    {

    switch (this)

    {

    case Bme280 _:

    _calibrationData=new Bme280CalibrationData();

    _controlRegister=(byte)Bmx280Register.CTRL_MEAS;

    break;

    case Bmp280 _:

    _calibrationData=new Bmp280CalibrationData();

    _controlRegister=(byte)Bmx280Register.CTRL_MEAS;

    break;

    case Bme680 _:

    _calibrationData=new Bme680CalibrationData();

    _controlRegister=(byte)Bme680Register.CTRL_MEAS;

    break;

    default:

    throw new Exception("Bmxx80 device not correctly configured. Could not find calibraton data.");

    }

    _calibrationData.ReadFromDevice(this);

    }

    實際代碼使用條件編譯。這是因為該項目是多目標的,而該屬性僅在.NET5.0+中受支持。使用該屬性可以跳過運行時檢查(在構(gòu)造函數(shù)中),否則將需要這些檢查來滿足可空性要求,就像早期的.NET版本一樣。
    工具類

    我們改進了Windows Forms 設(shè)計器,使其能在.NET5.0及更高版本中運行,更改了支持WinRT的方式,并進行了其他改進。

    Windows窗體設(shè)計器

    Windows窗體設(shè)計器(用于.NET Core 3.1和.NET5.0)已在Visual Studio 16.8中進行了更新,現(xiàn)在支持所有Windows窗體控件。設(shè)計器包括您指導的所有設(shè)計器功能,包括:拖放、選擇、移動和調(diào)整大小、控件的剪切/復制/粘貼/刪除、與屬性窗口的集成、事件生成等。數(shù)據(jù)綁定和對更廣泛的第三方控件集的支持很快就會到來。


    .NET 5.0目標框架

    在.NET5.0中,我們更改了用于目標框架的方法。以下項目文件演示了新的.NET5.0目標框架。

    1

    2

    3

    4

    5

    6

    7

    8

    <Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>net5.0</TargetFramework>

    </PropertyGroup>

    </Project>

      

    新的net5.0表單比我們之前使用的樣式更緊湊、更直觀。此外,我們正在擴展目標框架以描述操作系統(tǒng)依賴關(guān)系。我們希望通過.NET 6.0中的Xamarin定位iOS和Android,從而推動了這一變化。
    net5.0netcoreapp3.1

    Windows桌面API(包括Windows窗體、WPF和WinRT)僅在面向net5.0-windows時可用。您可以指定操作系統(tǒng)版本,如net5.0-Windows7或net5.0-windows10.0.17763.0(適用于Windows 2018年10月更新)。如果您想要使用WinRT API,則需要瞄準Windows 10版本。
    當使用新的net5.0-windows tfm時,跨平臺的場景可能會更具挑戰(zhàn)性。例如,System.Device.Gpio演示了一種用于管理Windows目標框架的模式,例如,如果您希望避免為Windows構(gòu)建或避免在Linux上拉取Windows運行時包。
    更新摘要:

    • l Net5.0是.NET5.0的新目標框架Moniker (TFM)。
    • l Net5.0結(jié)合并取代了netcoreapp和netStandard tfms。
    • l Net5.0支持.NET Framework兼容模式。
    • l Net5.0-Windows將用于公開特定于Windows的功能,包括Windows Forms、WPF和WinRT API。
    • l 特定于操作系統(tǒng)的TFMS可以包括操作系統(tǒng)版本號,如net6.0-ios14。
    • l 像ASP.NET Core這樣的可移植API將可以在net5.0上使用。同樣的情況也適用于Net6.0的Xamarin Forms。

    Visual Studio 16.8中的模板仍然以.NET Core 3.1為目標,用于控制臺、WPF和Windows窗體應用程序。ASP.NET模板已更新為支持.NET5.0。我們將在Visual Studio 16.9中更新其余模板的模板。

    WinRT Interop(重大更改)

    關(guān)于以Windows API為目標的主題,我們已經(jīng)轉(zhuǎn)向了一個新的模型,將WinRT API作為.NET5.0的一部分來支持。這包括調(diào)用API(雙向;CLR<==>WinRT),兩個類型系統(tǒng)之間的數(shù)據(jù)封送處理,以及要在類型系統(tǒng)或ABI邊界上被同等對待的類型的統(tǒng)一(即“投影類型”;IEnumerable和IIterable就是例子)。

    現(xiàn)有的WinRT互操作系統(tǒng)已作為.NET5.0的一部分從.NET運行時中移除。這是一個突破性的變化。這意味著使用WinRT和.NET Core 3.x的應用程序和庫需要重新構(gòu)建,不能按原樣在.NET5.0上運行。使用WinRT API的庫需要多目標來管理.NET Core 3.1和.NET5.0之間的這種差異。
    展望未來,我們將依靠WinRT團隊在Windows中提供的新CsWinRT工具。它生成基于C#的WinRT互操作程序集,這些程序集可以通過NuGet交付。這正是Windows團隊正在為Windows中的WinRT API所做的事情。任何想要使用WinRT(在Windows上)作為互操作系統(tǒng)的人都可以使用該工具,以將本機API公開給.NET或?qū)?NETAPI公開給本機代碼。
    CsWinRT工具在邏輯上類似于tlbimp和tlbexp,但要好得多。TLB工具依賴于.NET運行時中的大量COM互操作管道。CsWinRT工具只依賴于公共的.NETAPI。也就是說,C#9中的函數(shù)指針功能--在.NET5.0運行時中部分實現(xiàn)了--在一定程度上是受到CsWinRT工具需求的啟發(fā)。
    這種新的WinRT互操作模型有幾個好處:

    • l 它可以獨立于.NET運行時進行開發(fā)和改進。
    • l 它與為iOS和Android等其他操作系統(tǒng)提供的基于工具的互操作系統(tǒng)是對稱的。
    • l 該工具可以利用其他.NET特性(AOT、C#特性、IL鏈接),而這在以前的系統(tǒng)中不是一個選項。
    • l 簡化了.NET運行時代碼庫。

    使用WinRT API不需要添加NuGet引用。以Windows10TFM為目標--剛才在.NET5.0TFM一節(jié)中已經(jīng)討論過了--已經(jīng)足夠了。如果您的目標是.NET Core 3.1或更早版本,則需要引用WinRT包。您可以在System.Device.Gpio項目中看到此模式。
    原生導出

    很長一段時間以來,我們一直要求為調(diào)用.NET代碼的本機二進制文件啟用導出。該場景的構(gòu)建塊是托管對UnManagedCeller sOnlyAttribute的API支持。
    此功能是創(chuàng)建更高級別體驗的構(gòu)建塊。我們團隊中的Aaron Robinson一直致力于一個.NET Native Exports項目,該項目為將.NET組件發(fā)布為本機庫提供了更完整的體驗。我們正在尋找有關(guān)此功能的反饋,以幫助決定是否應將該方法包含在產(chǎn)品中。
    .NET原生導出項目使您能夠:

    • l 公開自定義本機導出。
    • l 不需要像COM這樣的更高級別的互操作技術(shù)。
    • l 跨平臺工作。
    • 有一些現(xiàn)有的項目支持類似的場景,例如:
    • l 不受管理的出口。
    • l DllExport

    多年來,我們在本機應用程序中看到了各種.NET托管模型。@rseanHall為此提出并實現(xiàn)了一種新穎的新模型,該模型利用了.NET應用程序托管層提供的所有內(nèi)置應用程序功能(特別是加載依賴項),同時允許從本機代碼調(diào)用自定義入口點。這在很多情況下都是完美的,可以想象在從本機應用程序托管.NET組件的開發(fā)人員中變得流行起來。這在以前是不存在的。謝謝你的貢獻,@rseanHall。

    兩個主要PR:

    • l 啟用從應用上下文調(diào)用Get_Runtime_Delegate。
    • l 實現(xiàn)HDT_GET_Function_POINTER

    事件管道
    事件管道是我們在.NET Core 2.2中添加的一個新的子系統(tǒng)和API,它可以在任何操作系統(tǒng)上執(zhí)行性能和其他診斷調(diào)查。在.NET5.0中,事件管道已得到擴展,使探查器能夠編寫事件管道事件。此場景對于檢測以前依賴ETW(在Windows上)監(jiān)視應用程序行為和性能的探查器至關(guān)重要。
    現(xiàn)在可以通過事件管道獲得程序集加載信息。這一改進是使類似的診斷功能(例如Fusion Log Viewer)成為.NET Framework的一部分的開始。現(xiàn)在,您可以使用以下命令,使用Dotnet-TRACE來收集此信息:

    dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4:4 -- ./MyApp –my-arg 1

    該工作流程在DotNet-TRACE文檔中進行了說明。您可以看到簡單測試應用程序的程序集加載信息。


    Microsoft.Extensions.Logging

    我們對Microsoft.Extensions.Logging庫中的控制臺日志提供程序進行了改進。現(xiàn)在,您可以實現(xiàn)自定義ConsoleForMatter來完全控制控制臺輸出的格式化和彩色化。格式化程序API通過實現(xiàn)VT-100(受大多數(shù)現(xiàn)代終端支持)轉(zhuǎn)義序列的子集來實現(xiàn)豐富的格式化。控制臺記錄器可以解析出不支持的終端上的轉(zhuǎn)義序列,允許您為所有終端編寫一個格式化程序。

    除了對定制格式化程序的支持之外,我們還添加了一個內(nèi)置的JSON格式化程序,它可以將結(jié)構(gòu)化的JSON日志發(fā)送到控制臺。

    轉(zhuǎn)儲調(diào)試

    調(diào)試托管代碼需要了解托管對象和構(gòu)造。數(shù)據(jù)訪問組件(DAC)是運行時執(zhí)行引擎的子集,它了解這些構(gòu)造,可以在沒有運行時的情況下訪問這些托管對象。在Linux上收集的.Net Core進程轉(zhuǎn)儲現(xiàn)在可以在Windows上使用WinDBG或DotNet Dump Analyze進行分析。

    我們還添加了對從MacOS上運行的.NET進程捕獲ELF轉(zhuǎn)儲的支持。由于ELF不是MacOS上的本機可執(zhí)行文件格式(像lldb這樣的本機調(diào)試器不能處理這些轉(zhuǎn)儲),我們將其作為一種選擇加入的特性。要在MacOS上啟用轉(zhuǎn)儲收集支持,請設(shè)置環(huán)境變量COMPLUS_DbgEnableElfDumpOnMacOS=1。生成的轉(zhuǎn)儲可以使用DotNet Dump Analyze進行分析。

    打印環(huán)境信息

    隨著.NET擴展了對新操作系統(tǒng)和芯片體系結(jié)構(gòu)的支持,人們有時想要一種打印環(huán)境信息的方式。我們創(chuàng)建了一個簡單的.NET工具來完成此任務(wù),名為dotnet-runtimeinfo。

    您可以使用以下命令安裝和運行該工具。

    1

    2

    dotnet tool install -f dotnet-runtimeinfo

    dotnet-runtimeinfo

    該工具為您的環(huán)境生成以下形式的輸出。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    **.NET information

    Version: 5.0.0

    FrameworkDescription: .NET 5.0.0

    Libraries version: 5.0.0

    Libraries hash: cf258a14b70ad9069470a108f13765e0e5988f51

    **Environment information

    OSDescription: Linux 5.8.6-1-MANJARO-ARM #1 SMP Thu Sep 3 22:01:08 CEST 2020

    OSVersion: Unix 5.8.6.1

    OSArchitecture: Arm64

    ProcessorCount: 6

    **CGroup info**

    cfs_quota_us: -1

    memory.limit_in_bytes: 9223372036854771712

    memory.usage_in_bytes: 2740666368

    運行時和庫
    在運行時和庫中有很多改進
    RyuJIT的代碼質(zhì)量改進
    這個版本對JIT有很多改進,我在以前的.NET5.0預覽帖中分享了其中的許多改進。在這篇文章中,我提升了來自社區(qū)的改變。

    • l 將xmm用于堆棧prolog-dotnet/Runtime#32538-更改為x86/x64 prolog零位調(diào)整代碼。改進:JSON;TechEmpower。致謝:本·亞當斯。
    • l 用于ARM64的Vectorise位數(shù)組-Dotnet/Runtime#33749-BitArray類已更新,包括使用ARM64內(nèi)部結(jié)構(gòu)的ARM64硬件加速實現(xiàn)。BitArray的性能改進非常顯著。感謝@Gnbrkm41。
    • l 動態(tài)通用詞典擴展特性dotnet/運行時#32270-一些(可能是大多數(shù)?)。基于改進了運行庫用來存儲有關(guān)泛型類型和方法的信息的低級(本機代碼)字典的實現(xiàn),泛型的使用現(xiàn)在有了更好的性能(最初的性能發(fā)現(xiàn))。有關(guān)更多信息,請參見Perf:COLLECTION COUNT()在Core中比CLR慢。錯誤報告歸功于@RealDotNetDave。
    • l Implementate Vector.Celing/Vector.Floor Dotnet/Runtime#31993-按照API提案,使用x64和Arm64內(nèi)部函數(shù)實現(xiàn)Vector.Celing/Vector.Floor。感謝@Gnbrkm41。
    • l TailCall助手的新的、更快的、可移植的實現(xiàn)。來源:Jakob Botsch Nielsen(.NET團隊實習生)。來自@dsymetweet的反應。
    • l 添加VectorTableList和TableVectorExtension內(nèi)部-Credit:@TamarChristinaArm(ARM Holdings)。
    • l 使用新的硬件內(nèi)部組件BSF/BSR-Credit@saucecontrol提高英特爾架構(gòu)性能。
    • l 實現(xiàn)向量{Size}.AllBitsSet-Credit@Gnbrkm41。
    • l 允許逃避一些邊界檢查-Credit@Nathan-Moore

    垃圾收集器GC
    在GC中進行了以下改進。

    • l 卡片標記竊取-dotnet/coreclr#25986-服務(wù)器GC(在不同線程上)現(xiàn)在可以工作竊取,同時標記由老一代對象持有的0/1類對象。這意味著,在某些GC線程標記時間比其他線程長得多的情況下,短暫的GC暫停會更短。
    • l 引入固定對象堆-DotNet/Runtime#32283-添加固定對象堆(PoH)。這個新堆(大對象堆(LOH)的對等體)將允許GC單獨管理固定對象,從而避免固定對象對世代堆的負面影響。
    • l 允許從空閑列表分配大對象,同時后臺使用空閑列表清理啟用了SOH的LOH分配,而BGC正在清理SOH。以前,這只在LOH上使用段末尾空間。這允許更好地使用堆。
    • l 后臺GC掛起修復-dotnet/coreclr#27729-掛起修復減少了bgc和用戶線程掛起的時間。這減少了在GC發(fā)生之前掛起托管線程所需的總時間。Dotnet/coreclr#27578也促成了同樣的結(jié)果。
    • l 修正了擴展塢中的命名組組處理,增加了對從命名組組讀取限制的支持。以前我們只讀全球版本。
    • l 優(yōu)化矢量化排序-Dotnet/Runtime#37159-GC中的矢量化標記列表排序,減少了短暫的GC暫停時間(也包括Dotnet/Runtime#40613)。
    • l 世代感知分析-DotNet/Runtime#40322-世代感知分析,允許您確定哪些老一代對象保留在年輕一代對象上,從而使它們存活下來,并導致短暫的GC暫停時間。
    • l 優(yōu)化分解GC堆內(nèi)存頁面-Dotnet/Runtime#35896-優(yōu)化分解,更好地分解邏輯,對于服務(wù)器GC來說,完全退出了“停止世界”階段,從而減少了阻塞GC的暫停時間。

    現(xiàn)在,GC通過EgGetGCMmemyInfo方法公開最新集合的詳細信息。GCMmemyInfo結(jié)構(gòu)提供有關(guān)機器內(nèi)存、堆內(nèi)存和您指定的GC類型的最新集合或最新集合的信息-臨時GC、完全阻塞GC或后臺GC。
    使用這個新API的最有可能的用例是日志記錄/監(jiān)視,或者向加載器平衡器指示機器應該停止旋轉(zhuǎn)以請求完整的GC。它還可以通過減小緩存大小來避免容器硬限制。
    另一個小而有效的改變是將昂貴的重置內(nèi)存操作推遲到內(nèi)存不足的情況。我們預計策略中的這些更改將降低GC延遲(以及總體上的GC CPU使用率)。
    Windows ARM64

    現(xiàn)在,.NET應用程序可以在Windows Arm64上本地運行。在此之前,我們在.NETCore3.0中添加了對Linux Arm64的支持(對Glibc和MUSL的支持)。使用.NET 5.0,您可以在Windows Arm64設(shè)備(如Surface Pro X)上開發(fā)和運行應用程序。您已經(jīng)可以在Windows Arm64上運行.NET Core和.NET Framework應用程序,但需要通過x86仿真。這是可行的,但是原生ARM64執(zhí)行的性能要好得多。
    針對ARM64的MSI安裝程序是此版本的最終更改之一。您可以在下圖中看到.NET5.0SDK安裝程序。


    NET 5.0 SDK目前不包含Windows Arm64上的Windows桌面組件-Windows Forms和WPF。這一變化最初是在.NET5.0預覽版8中發(fā)布的。我們希望在5.0服務(wù)更新中添加Windows Arm64的Windows桌面包。我們目前還沒有可以分享的日期。在此之前,Windows Arm64支持SDK、控制臺和ASP.NET Core應用程序,但Windows桌面組件不支持。

    ARM64性能

    一年多來,我們在提高ARM64性能方面投入了大量資金。我們致力于使ARM64成為一個基于.NET的高性能平臺。這些改進同樣適用于Windows和Linux。平臺可移植性和一致性一直是.NET令人信服的特點。這包括無論您在哪里使用.NET都能提供出色的性能。在.NET Core 3.x中,ARM64的功能與x64不相上下,但缺少一些關(guān)鍵的性能特性和投資。我們已經(jīng)在.NET5.0中解決了這個問題,正如在.NET5.0中的ARM64性能中所描述的那樣。

    改進之處在于:

    • l 調(diào)整ARM64的JIT優(yōu)化(示例)。
    • l 啟用并利用ARM64硬件特性(示例)。
    • l 調(diào)整ARM64庫中的關(guān)鍵性能算法(例如)。

    有關(guān)更多詳細信息,請參見在.NET5.0中提高Arm64性能。

    硬件內(nèi)部屬性是我們在.NET Core3.0中添加的一個低級性能特性。當時,我們增加了對x86-64指令和芯片的支持。作為.NET5.0的一部分,我們正在擴展該功能以支持ARM64。僅僅創(chuàng)建內(nèi)部結(jié)構(gòu)并不能提高性能。它們需要在性能關(guān)鍵型代碼中使用。我們在.NET5.0的.NET庫中廣泛利用了Arm64的內(nèi)部特性。您也可以在自己的代碼中做到這一點,盡管您需要熟悉CPU指令才能做到這一點。

    我將用一個類比來解釋硬件內(nèi)部是如何工作的。在很大程度上,開發(fā)人員依賴于.NET中內(nèi)置的類型和API,比如string.Split或HttpClient。這些API通常通過P/Invoke功能利用本地操作系統(tǒng)API。P/Invoke支持高性能的本機互操作,并在.NET庫中為此廣泛使用。您可以自己使用相同的功能來調(diào)用本機API。硬件內(nèi)部功能類似,不同之處在于它們不是調(diào)用操作系統(tǒng)API,而是使您能夠在代碼中直接使用CPU指令。它大致相當于C++內(nèi)部函數(shù)的.NET版本。硬件本質(zhì)最好被認為是一種CPU硬件加速功能。它們提供了非常實實在在的好處,現(xiàn)在是.NET庫性能基礎(chǔ)的關(guān)鍵部分,并負責您可以在.NET5.0性能帖子中讀到的許多好處。與C++相比,當.NET內(nèi)部函數(shù)被AOT編譯成隨時可以運行的文件時,內(nèi)部函數(shù)沒有運行時性能損失。
    注意:Visual C++編譯器具有類似的內(nèi)部特性。您可以直接將C++與.NET硬件內(nèi)部功能進行比較,如果您在System.Rune me.Intrinsics.X86.Avx2、x64(AMD64)內(nèi)部功能列表和英特爾內(nèi)部功能指南中搜索_mm_i32ather_ep32,就可以看到這一點。你會看到很多相似之處。
    我們在5.0中對ARM64的性能進行了第一次重大投資,并將在后續(xù)版本中繼續(xù)這方面的努力。我們直接與ARM Holdings的工程師合作,確定產(chǎn)品改進的優(yōu)先順序,并設(shè)計最充分利用ARMv8 ISA的算法。其中一些改進將為ARM32帶來價值,然而,我們并沒有將獨特的努力應用于ARM32。如果你使用的是Raspberry Pi,如果你安裝了新的Arm64版本的Raspberry Pi OS,你會享受到這些改進。
    我們預計蘋果將在任何時候發(fā)布新的蘋果硅基Mac電腦。我們已經(jīng)有了針對Apple Silicon的.NET6.0的早期版本,并一直在與蘋果的工程師合作,幫助為該平臺優(yōu)化.NET。我們在Apple Silicon(Credit@Sickler)上也有一些早期的社區(qū)參與。

    P95+延遲
    我們看到越來越多的大型面向互聯(lián)網(wǎng)的網(wǎng)站和服務(wù)托管在.NET上。雖然有很多合理的關(guān)注點放在每秒請求數(shù)(RPS)指標上,但我們發(fā)現(xiàn)沒有大的網(wǎng)站所有者問我們這個問題或要求數(shù)百萬的RPS。然而,我們聽說了很多關(guān)于延遲的事情,特別是關(guān)于改善P95或P99延遲的問題。通常,為站點配置的機器或核心的數(shù)量(以及最大的成本驅(qū)動因素)是根據(jù)達到特定的P95指標(而不是P50)來選擇的。我們認為延遲是真正的“金錢指標”。
    我們在Stack Overflow的朋友們在分享他們服務(wù)上的數(shù)據(jù)方面做得很好。他們的一位工程師尼克·克雷弗(Nick Craver)最近分享了他們在遷移到.NET Core后看到的延遲改進:

    鎖定對象一直是GC性能的長期挑戰(zhàn),特別是因為它們加速(或?qū)е?內(nèi)存碎片。我們?yōu)楣潭▽ο筇砑恿艘粋€新的GC堆。固定對象堆基于這樣的假設(shè),即進程中固定的對象非常少,但它們的存在會造成不成比例的性能挑戰(zhàn)。將固定對象(尤其是那些由.NET庫作為實現(xiàn)細節(jié)創(chuàng)建的對象)移動到一個獨特的區(qū)域是有意義的,這樣會使世代GC堆中只有很少的固定對象,甚至沒有固定對象,因此性能會大大提高。
    最近,我們一直在應對大中華區(qū)長期存在的挑戰(zhàn)。DotNet/Runtime#2795應用了一種新的GC靜態(tài)掃描方法,在確定GC堆對象的活躍度時避免了鎖爭用。Dotnet/Runtime#25986使用了一種新算法,用于在垃圾收集的標記階段跨核心平衡GC工作,這應該會增加大堆垃圾收集的吞吐量,進而減少延遲。

    提高分層編譯的性能

    我們一直致力于改進多版本的分層編譯。我們繼續(xù)將其視為一個關(guān)鍵的性能特性,無論是啟動性能還是穩(wěn)態(tài)性能。在這個版本中,我們對分層編譯做了兩大改進。
    分層編譯的主要機制是調(diào)用計數(shù)。一旦一個方法被調(diào)用n次,運行庫就會要求JIT以更高的質(zhì)量重新編譯該方法。從我們最早的性能分析中,我們知道呼叫計數(shù)機制太慢,但沒有看到一個簡單的方法來解決這個問題。作為.NET5.0的一部分,我們改進了分層JIT編譯使用的調(diào)用計數(shù)機制,以平滑啟動時的性能。在過去的版本中,我們看到了在進程生命周期的前10-15秒(主要是Web服務(wù)器)中出現(xiàn)的不可預測的性能報告。這個問題現(xiàn)在應該得到解決。
    我們發(fā)現(xiàn)的另一個性能挑戰(zhàn)是對帶有循環(huán)的方法使用分層編譯。根本問題是,您可以使用一個循環(huán)多次的冷方法(只調(diào)用一次或幾次;$lt;n)。我們稱這種病態(tài)場景為“冷方法;熱循環(huán)”。很容易想象這種情況會發(fā)生在應用程序的Main方法中。因此,默認情況下,我們禁用了具有循環(huán)的方法的分層編譯。相反,我們允許應用程序選擇使用帶循環(huán)的分層編譯。PowerShell是在看到某些場景的高個位數(shù)性能改進后選擇這樣做的應用程序。
    為了更好地處理具有循環(huán)的方法,我們實現(xiàn)了棧上替換(OSR)。這類似于Java虛擬機具有的同名功能。OSR使當前正在運行的方法執(zhí)行的代碼能夠在方法執(zhí)行過程中重新編譯,而這些方法是活動的“堆棧上”。這一功能目前還處于試驗階段和選擇加入階段,并且僅在x64上。
    要使用OSR,必須啟用多項功能。PowerShell項目文件是一個很好的起點。您會注意到,分層編譯和所有快速JIT功能都已啟用。此外,需要將COMPLUS_TC_OnStackReplace環(huán)境變量設(shè)置為1。
    或者,您也可以設(shè)置以下兩個環(huán)境變量,假設(shè)所有其他設(shè)置都有其缺省值:
    COMPLUS_TC_QuickJitForLoops=1。
    COMPLUS_TC_OnStackReplace=1。
    我們不打算在.NET5.0中默認啟用OSR,也還沒有決定是否會在生產(chǎn)中支持它。

    在Windows上支持ICU

    我們使用ICU庫來支持Unicode和全球化,以前只在Linux和MacOS上使用。我們現(xiàn)在在Windows 10上使用相同的庫。這一更改使得全球化API的行為在Windows 10、MacOS和Linux之間保持一致,例如特定于區(qū)域性的字符串比較。我們還將ICU與Blazor WebAssembly配合使用。

    將System.DirectoryServices.Protooles擴展到Linux和MacOS

    我們一直在添加對System.DirectoryServices.Protooles的跨平臺支持。這包括對Linux的支持和對MacOS的支持。Windows支持是預先存在的。
    協(xié)議是一個比System.DirectoryServices更低級的API,可以支持(或可以用來支持)更多場景。System.DirectoryServices包含僅限Windows的概念/實現(xiàn),因此它不是跨平臺的明顯選擇。這兩個API集都支持控制目錄服務(wù)服務(wù)器并與其交互,如LDAP或Active Directory。

    System.Text.Json

    System.Text.Json在.NET5.0中得到了顯著改進,以提高性能和可靠性,并使熟悉Newtonsoft.Json的人們更容易采用。它還支持將JSON對象反序列化為記錄。
    如果您正在考慮使用System.Text.Json作為Newtonsoft.Json的替代方案,您應該查看遷移指南。本指南闡明了這兩個API之間的關(guān)系。Json旨在涵蓋許多與Newtonsoft.Json相同的場景,但它并不是要替代流行的JSON庫,也不是要實現(xiàn)與流行的JSON庫相同的功能。我們試圖在性能和可用性之間保持平衡,在我們的設(shè)計選擇中偏向于性能。

    HttpClient擴展方法

    JsonSerializer擴展方法現(xiàn)在在HttpClient上公開,極大地簡化了這兩個API的結(jié)合使用。這些擴展方法消除了復雜性,并為您處理了各種場景,包括處理內(nèi)容流和驗證內(nèi)容媒體類型。Steve Gordon很好地解釋了在System.Net.Http.Json中使用HttpClient發(fā)送和接收JSON的好處。
    下面的示例將天氣預報JSON數(shù)據(jù)反序列化為Forecast記錄,使用新的

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    using System;

    using System.Net.Http;

    using System.Net.Http.Json;

    string serviceURL="https://localhost:5001/WeatherForecast";

    HttpClient client=new();

    Forecast[] forecasts=await client.GetFromJsonAsync<Forecast[]>(serviceURL);

    foreach(Forecast forecast in forecasts)

    {

    Console.WriteLine($"{forecast.Date}; {forecast.TemperatureC}C; {forecast.Summary}");

    }

    // {"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}

    public record Forecast(DateTime Date, int TemperatureC, int TemperatureF, string Summary);

    這段代碼很緊湊!它依賴于C#9中的頂級程序和記錄以及新的GetFromJsonAsync<T>()擴展方法。在如此接近的情況下使用Foreach和Await可能會讓您懷疑,我們是否要添加對JSON對象流的支持。我真的希望如此。
    您可以在自己的機器上嘗試此功能。以下.NET SDK命令將使用WebAPI模板創(chuàng)建天氣預報服務(wù)。默認情況下,它將在以下網(wǎng)址公開服務(wù):https://localhost:5001/WeatherForecast.。這與示例中使用的URL相同。

    1

    2

    3

    rich@thundera ~ % dotnet new webapi -o webapi

    rich@thundera ~ % cd webapi

    rich@thundera webapi % dotnet run

    確保您已經(jīng)運行了DotNet dev-certs https--首先信任,否則客戶端和服務(wù)器之間的握手將不起作用。如果遇到問題,請參閱信任ASP.NET核心HTTPS開發(fā)證書。
    然后,您可以運行上一個示例。

    1

    2

    3

    4

    5

    6

    7

    8

    rich@thundera ~ % git clone https://gist.github.com/3b41d7496f2d8533b2d88896bd31e764.git weather-forecast

    rich@thundera ~ % cd weather-forecast

    rich@thundera weather-forecast % dotnet run

    9/9/2020 12:09:19 PM; 24C; Chilly

    9/10/2020 12:09:19 PM; 54C; Mild

    9/11/2020 12:09:19 PM; -2C; Hot

    9/12/2020 12:09:19 PM; 24C; Cool

    9/13/2020 12:09:19 PM; 45C; Balmy

    改進了對不可變類型的支持
    定義不可變類型有多種模式。記錄只是最新的記錄。JsonSerializer現(xiàn)在支持不可變類型。
    在本例中,您將看到帶有不可變結(jié)構(gòu)的序列化。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    using System;

    using System.Text.Json;

    using System.Text.Json.Serialization;

    var json="{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"} ";

    var options=new JsonSerializerOptions()

    {

    PropertyNameCaseInsensitive=true,

    IncludeFields=true,

    PropertyNamingPolicy=JsonNamingPolicy.CamelCase

    };

    var forecast=JsonSerializer.Deserialize<Forecast>(json, options);

    Console.WriteLine(forecast.Date);

    Console.WriteLine(forecast.TemperatureC);

    Console.WriteLine(forecast.TemperatureF);

    Console.WriteLine(forecast.Summary);

    var roundTrippedJson=JsonSerializer.Serialize<Forecast>(forecast, options);

    Console.WriteLine(roundTrippedJson);

    public struct Forecast{

    public DateTime Date {get;}

    public int TemperatureC {get;}

    public int TemperatureF {get;}

    public string Summary {get;}

    [JsonConstructor]

    public Forecast(DateTime date, int temperatureC, int temperatureF, string summary)=> (Date, TemperatureC, TemperatureF, Summary)=(date, temperatureC, temperatureF, summary);

    }

      

    注意:JsonConstructor屬性是指定要與結(jié)構(gòu)一起使用的構(gòu)造函數(shù)所必需的。對于類,如果只有一個構(gòu)造函數(shù),則不需要該屬性。記錄也是如此。
    它會產(chǎn)生以下輸出:

     

    1

    2

    3

    4

    5

    6

    rich@thundera jsonserializerimmutabletypes % dotnet run

    9/6/2020 11:31:01 AM

    -1

    31

    Scorching

    {"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}

    支持記錄
    JsonSerializer對記錄的支持幾乎與我剛才向您展示的對不可變類型的支持相同。我想在這里展示的不同之處在于將JSON對象反序列化為一個記錄,該記錄公開了一個參數(shù)化的構(gòu)造函數(shù)和一個可選的init屬性。
    以下是程序片段,包括Record定義:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    using System;

    using System.Text.Json;

    Forecast forecast=new(DateTime.Now, 40)

    {

    Summary="Hot!"

    };

    string forecastJson=JsonSerializer.Serialize<Forecast>(forecast);

    Console.WriteLine(forecastJson);

    Forecast? forecastObj=JsonSerializer.Deserialize<Forecast>(forecastJson);

    Console.Write(forecastObj);

    public record Forecast (DateTime Date, int TemperatureC)

    {

    public string? Summary {get; init;}

    };

    它會產(chǎn)生以下輸出:

    1

    2

    3

    rich@thundera jsonserializerrecords % dotnet run

    {"Date":"2020-09-12T18:24:47.053821-07:00","TemperatureC":40,"Summary":"Hot!"}

    Forecast { Date=9/12/2020 6:24:47 PM, TemperatureC=40, Summary=Hot! }

    改進了對Dictionary<K,V>的支持

    JsonSerializer現(xiàn)在支持使用非字符串鍵的字典。您可以在下面的示例中看到這是什么樣子。在.NET Core 3.0中,此代碼進行編譯,但會引發(fā)NotSupportdException異常。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    using System;

    using System.Collections.Generic;

    using System.Text.Json;

    Dictionary<int, string> numbers=new ()

    {

    {0, "zero"},

    {1, "one"},

    {2, "two"},

    {3, "three"},

    {5, "five"},

    {8, "eight"},

    {13, "thirteen"},

    {21, "twenty one"},

    {34, "thirty four"},

    {55, "fifty five"},

    };

    var json=JsonSerializer.Serialize<Dictionary<int, string>>(numbers);

    Console.WriteLine(json);

    var dictionary=JsonSerializer.Deserialize<Dictionary<int, string>>(json);

    Console.WriteLine(dictionary[55]);

    它會產(chǎn)生以下輸出。

    1

    2

    3

    rich@thundera jsondictionarykeys % dotnet run

    {"0":"zero","1":"one","2":"two","3":"three","5":"five","8":"eight","13":"thirteen","21":"twenty one","34":"thirty four","55":"fifty five"}

    fifty five

    對字段的支持

    JsonSerializer現(xiàn)在支持字段。這一變化是由@YohDeadfall貢獻的。謝謝!。
    您可以在下面的示例中看到這是什么樣子。在.NET Core 3.0中,JsonSerializer無法序列化或反序列化使用字段的類型。對于具有字段且無法更改的現(xiàn)有類型,這是一個問題。有了這一變化,這就不再是問題了。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    using System;

    using System.Text.Json;

    var json="{\"date\":\"2020-09-06T11:31:01.923395-07:00\",\"temperatureC\":-1,\"temperatureF\":31,\"summary\":\"Scorching\"} ";

    var options=new JsonSerializerOptions()

    {

    PropertyNameCaseInsensitive=true,

    IncludeFields=true,

    PropertyNamingPolicy=JsonNamingPolicy.CamelCase

    };

    var forecast=JsonSerializer.Deserialize<Forecast>(json, options);

    Console.WriteLine(forecast.Date);

    Console.WriteLine(forecast.TemperatureC);

    Console.WriteLine(forecast.TemperatureF);

    Console.WriteLine(forecast.Summary);

    var roundTrippedJson=JsonSerializer.Serialize<Forecast>(forecast, options);

    Console.WriteLine(roundTrippedJson);

    public class Forecast{

    public DateTime Date;

    public int TemperatureC;

    public int TemperatureF;

    public string Summary;

    }

    它會產(chǎn)生以下輸出。

    1

    2

    3

    4

    5

    6

    rich@thundera jsonserializerfields % dotnet run

    9/6/2020 11:31:01 AM

    -1

    31

    Scorching

    {"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}

    保留JSON對象圖中的引用

    JsonSerializer增加了對在JSON對象圖中保留(循環(huán))引用的支持。它通過存儲ID來實現(xiàn)這一點,當JSON字符串被反序列化為對象時,這些ID可以重新組成。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    using System;

    using System.Collections.Generic;

    using System.Text.Json;

    using System.Text.Json.Serialization;

    Employee janeEmployee=new()

    {

    Name="Jane Doe",

    YearsEmployed=10

    };

    Employee johnEmployee=new()

    {

    Name="John Smith"

    };

    janeEmployee.Reports=new List<Employee> { johnEmployee };

    johnEmployee.Manager=janeEmployee;

    JsonSerializerOptions options=new()

    {

    // NEW: globally ignore default values when writing null or default

    DefaultIgnoreCondition=JsonIgnoreCondition.WhenWritingDefault,

    // NEW: globally allow reading and writing numbers as JSON strings

    NumberHandling=JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString,

    // NEW: globally support preserving object references when (de)serializing

    ReferenceHandler=ReferenceHandler.Preserve,

    IncludeFields=true, // NEW: globally include fields for (de)serialization

    WriteIndented=true,};

    string serialized=JsonSerializer.Serialize(janeEmployee, options);

    Console.WriteLine($"Jane serialized: {serialized}");

    Employee janeDeserialized=JsonSerializer.Deserialize<Employee>(serialized, options);

    Console.Write("Whether Jane's first report's manager is Jane: ");

    Console.WriteLine(janeDeserialized.Reports[0].Manager==janeDeserialized);

    public class Employee

    {

    // NEW: Allows use of non-public property accessor.

    // Can also be used to include fields "per-field", rather than globally with JsonSerializerOptions.

    [JsonInclude]

    public string Name { get; internal set; }

    public Employee Manager { get; set; }

    public List<Employee> Reports;

    public int YearsEmployed { get; set; }

    // NEW: Always include when (de)serializing regardless of global options

    [JsonIgnore(Condition=JsonIgnoreCondition.Never)]

    public bool IsManager=> Reports?.Count > 0;

    }

    性能

    在.NET5.0中,JsonSerializer的性能得到了顯著提高。Stephen Toub在他的.NET5帖子中談到了JsonSerializer的一些性能改進。我還在.NET5.0RC1文章中更詳細地介紹了Json的性能。

    應用程序部署

    在編寫或更新應用程序之后,您需要部署它以使您的用戶受益。這可能是到Web服務(wù)器、云服務(wù)或客戶端計算機,也可能是使用Azure DevOps或GitHub操作等服務(wù)的CI/CD流的結(jié)果。
    我們努力提供一流的部署功能,自然地與應用程序類型保持一致。對于.NET5.0,我們專注于改進單文件應用程序,減少停靠多階段構(gòu)建的容器大小,并為使用.NET Core部署ClickOnce應用程序提供更好的支持。

    容器

    我們認為容器是最重要的云趨勢,并在這方面投入了大量資金。我們正在以多種方式投資容器,在.NET軟件堆棧的多個級別上。首先是我們對基本面的投資,這越來越多地受到容器場景和部署容器應用的開發(fā)者的影響。
    我們正在讓與集裝箱管弦樂團的合作變得更容易。我們已經(jīng)添加了OpenTelemeter支持,這樣您就可以從您的應用程序中捕獲分布式跟蹤和指標。DotNet-monitor是一種新工具,旨在作為從.NET進程訪問診斷信息的主要方式。特別是,我們已經(jīng)開始構(gòu)建dotnet-monitor的容器變體,您可以將其用作應用程序側(cè)車。最后,我們正在構(gòu)建DotNet/Tye,以此來提高微服務(wù)開發(fā)人員的工作效率,包括開發(fā)和部署到Kubernetes環(huán)境。
    NET運行時現(xiàn)在支持cgroup v2,我們預計它將在2020年后成為與容器相關(guān)的重要API。Docker目前使用的是cgroup v1(已經(jīng)被.NET支持)。相比之下,cgroup v2比cgroup v1更簡單、更高效、更安全。您可以通過我們2019年Docker更新了解更多關(guān)于cgroup和Docker資源限制的信息。Linux發(fā)行版和容器運行時正在添加對cgroup v2的支持。一旦cgroup v2環(huán)境變得更加普遍,.Net 5.0將在cgroup v2環(huán)境中正常工作。這歸功于Omair Majid,他在Red Hat支持.NET。
    除了Nano Server,我們現(xiàn)在還發(fā)布Windows Server Core鏡像。我們添加了Server Core,因為我們收到了客戶的反饋,他們想要一個與Windows Server完全兼容的.NET映像。如果你需要這個,那么這張新照片就是為你準備的。支持Windows Server 2019長期服務(wù)渠道(LTSC)、.NET5.0和x64的組合。我們還進行了其他更改,以減小Windows服務(wù)器核心映像的大小。這些改進帶來了很大的不同,但都是在Windows Server 2019發(fā)布之后做出的。然而,它們將使下一個Windows Server LTSC版本受益。
    作為使用“.NET”作為產(chǎn)品名稱的一部分,我們現(xiàn)在將.NET Core 2.1、3.1和.NET5.0鏡像發(fā)布到mcr.microsoft.com/dotnet系列的Repos中,而不是發(fā)布到mcr.microsoft.com/dotnet/core。我們將繼續(xù)將.NET Core 2.1和3.1雙重發(fā)布到以前的位置,同時支持這些版本。.Net 5.0圖像將僅發(fā)布到新位置。請相應地更新您的From語句和腳本。
    作為.NET5.0的一部分,我們將SDK鏡像重新建立在ASP.NET鏡像之上,而不是構(gòu)建包-dep,以顯著減小您在多階段構(gòu)建場景中拉取的聚合鏡像的大小。
    此更改對于多階段構(gòu)建有以下好處,其中包含一個示例Dockerfile:
    Ubuntu 20.04 Focus的多階段構(gòu)建成本:

    Pull Image

    Before

    After

    sdk:5.0-focal

    268 MB

    232 MB

    aspnet:5.0-focal

    64 MB

    10 KB (manifest only)

    減少了約: 100 MB (-30%)

    Debian 10 Buster的多階段構(gòu)建成本:

    Pull Image

    Before

    After

    sdk:5.0

    280 MB

    218 MB

    aspnet:5.0

    84 MB

    4 KB (manifest only)

    減少了約: 146 MB (-40%)

    有關(guān)更多詳細信息,請參見Dotnet/Dotnet-docker#1814。
    此更改有助于多階段構(gòu)建,其中SDK和您的目標aspnet或運行時鏡像的版本相同(我們預計這是常見的情況)。在進行此更改時,(例如)aspnet拉入將是不可行的,因為您將通過最初的SDK拉入拉出aspnet層。
    我們對阿爾卑斯和Nano服務(wù)器做了類似的更改。阿爾卑斯和Nano服務(wù)器都沒有Buildpack-dep鏡像。但是,阿爾卑斯和Nano Server的SDK鏡像之前并不是在ASP.NET鏡像之上構(gòu)建的。我們解決了這個問題。你將會看到阿爾卑斯和Nano服務(wù)器以及5.0版本在多階段構(gòu)建方面都獲得了巨大的成功。

    單文件應用程序

    單個文件應用程序作為單個文件發(fā)布和部署。該應用程序及其依賴項都包含在該文件中。當應用程序運行時,依賴項直接從該文件加載到內(nèi)存中(不會影響性能)。
    在.NET5.0中,單文件應用程序主要集中在Linux上(稍后會詳細介紹)。它們可以是依賴于框架的,也可以是獨立的。依賴于全球安裝的.NET運行時,依賴于框架的單個文件應用程序可能非常小。自包含的單文件應用程序較大(由于帶有運行庫),但不需要在安裝前安裝.NET運行庫,因此可以直接運行。一般來說,依賴于框架對開發(fā)和企業(yè)環(huán)境都有好處,而對于ISV來說,自包含通常是更好的選擇。
    我們用.NET Core 3.1制作了一個版本的單文件應用程序。它將二進制文件打包到單個文件中進行部署,然后將這些文件解壓縮到一個臨時目錄中以加載和執(zhí)行它們。在某些情況下,這種方法可能會更好,但我們希望我們?yōu)?.0構(gòu)建的解決方案會更好,這是一個值得歡迎的改進。
    要創(chuàng)建真正的單一文件解決方案,我們需要克服多個障礙。關(guān)鍵任務(wù)是創(chuàng)建一個更復雜的應用程序捆綁器,并教導運行庫從二進制資源加載程序集。我們還遇到了一些無法逾越的障礙。
    在所有平臺上,我們都有一個稱為“apphost”的組件。這是成為可執(zhí)行文件的文件,例如Windows上的myapp.exe或基于Unix的平臺上的./myapp。對于單一文件應用程序,我們創(chuàng)建了一個新的apphost,我們稱之為“超級主機”。它具有與常規(guī)apphost相同的角色,但還包括運行時的靜態(tài)鏈接副本。超級主機是我們單一文件方法的一個基本設(shè)計點。這個模型就是我們在帶有.NET5.0的Linux上使用的模型。由于各種操作系統(tǒng)的限制,我們無法在Windows或MacOS上實現(xiàn)這種方法。我們在Windows或MacOS上沒有超級主機。在這些操作系統(tǒng)上,本地運行時二進制文件(大約3個)位于單個文件應用程序旁邊(導致“不是單個文件”)。我們將在.NET6.0中重新討論這種情況,然而,我們預計我們遇到的問題仍然具有挑戰(zhàn)性。
    您可以使用以下命令來生成單文件應用程序。

    l 依賴框架的單文件APP:

    n DotNet PUBLISH-r Linux-x64--自含式FALSE/p:PublishSingleFile=TRUE。

    l 自含式單文件APP:

    n DotNet PUBLISH-r Linux-x64--自含式TRUE/p:PublishSingleFile=TRUE

    您還可以使用項目文件配置單個文件發(fā)布。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    <Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>net5.0</TargetFramework>

    <!-- The OS and CPU type you are targeting -->

    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>

    <!-- Determine self-contained or framework-dependent -->

    <SelfContained>true</SelfContained>

    <!-- Enable single file -->

    <PublishSingleFile>true</PublishSingleFile>

    </PropertyGroup>

    </Project>

    您可以嘗試使用程序集修剪來減小應用程序的大小。它可能會通過過度修剪來破壞應用程序,因此建議在使用此功能后徹底測試您的應用程序。程序集調(diào)整還會移除提前編譯的讀到運行本機代碼(用于被調(diào)整的程序集),這主要是為了提高性能。您需要在裁剪之后測試應用程序的性能。通過使用PublishReadyToRun屬性(并設(shè)置為true),您可以在裁剪后即可運行編譯您的應用程序。
    注:

    • l 應用程序是特定于操作系統(tǒng)和架構(gòu)的。您需要發(fā)布每種配置(Linuxx64、LinuxArm64、Windowsx64、…)。。
    • l 配置文件(如*.runtimeconfig.json)包含在單個文件中。如果需要,您可以在單個文件旁邊放置額外的配置文件(可能是為了測試)。
    • l 默認情況下,單個文件中不包括.pdb文件。您可以使用<DebugType>Embed</DebugType>屬性啟用PDB嵌入。
    • l IncludeNativeLibrariesForSelfExtract屬性可用于在Windows和MacOS上嵌入本機運行時二進制文件,但它們必須在運行時解壓縮到臨時存儲中。不建議在一般情況下使用此功能。

    ClickOnce

    多年來,ClickOnce一直是流行的.NET部署選項。現(xiàn)在,它被.NET Core 3.1和.NET5.0 Windows應用程序支持。當我們將Windows窗體和WPF支持添加到.NET Core 3.0中時,我們知道很多人會希望使用ClickOnce進行應用程序部署。在過去的一年里,.NET和Visual Studio團隊共同努力,在命令行和Visual Studio中啟用ClickOnce發(fā)布。
    從項目一開始,我們就有兩個目標:

    • l 在Visual Studio中為ClickOnce啟用熟悉的體驗。
    • l 使用MSBuild或MAGE工具,通過命令行流為ClickOnce發(fā)布啟用現(xiàn)代CI/CD。
    • 用圖片向你展示這種體驗是最容易的。


    讓我們從Visual Studio體驗開始,它以項目發(fā)布為中心。


    我們目前支持的主要部署模式是依賴于框架的應用程序。很容易依賴于.NET桌面運行時(即包含WPF和Windows窗體的桌面運行時)。如果需要,ClickOnce安裝程序?qū)⒃谟脩粲嬎銠C上安裝.NET運行時。我們還打算支持獨立和單一文件應用程序。


    您可能會想,您是否仍然能夠利用ClickOnce脫機和更新功能。可以,停那兒吧。


    MAGE最大的變化是它現(xiàn)在是一個.NET工具,發(fā)布在NuGet上。這意味著你不需要在你的機器上安裝任何特殊的東西。您只需要.NET5.0SDK,然后就可以將MAGE安裝為一個.NET工具。您也可以使用它發(fā)布.NET Framework應用程序,但是,SHA1簽名和部分信任支持已被移除。
    MAGE安裝命令如下:

    dotnet tool install -g Microsoft.DotNet.Mage

    在您制作并分發(fā)了ClickOnce安裝程序之后,您的用戶將看到熟悉的ClickOnce安裝對話框。


    當您使更新可用時,您的用戶將看到更新對話框。


    最后總結(jié)

    Net 5.0是另一個大版本,它應該會改進你使用.NET的許多方面。我們已經(jīng)實現(xiàn)了一系列的改進,從單文件應用程序到性能,從Json序列化的可用性到ARM64的支持。雖然今天可能是您使用.NET5.0的第一天,但我們在微軟的產(chǎn)品中運行.NET5.0已經(jīng)有幾個月了。我們相信,它已準備好供您使用、運營您的業(yè)務(wù)并為您的應用程序提供動力。C#9和F#5中的新語言改進應該會使您的代碼更具表現(xiàn)力,更易于編寫。對于您現(xiàn)有的應用程序來說,.Net 5.0也是一個很好的選擇。在許多情況下,您可以毫不費力地升級。
    如果您對性能感興趣,您可能會對我們在TechEmpower基準測試方面的進展感興趣。回過頭來看,您可以看到.NETCore3.1在最新一輪第19輪中的表現(xiàn)相當不錯。我們期待著在即將到來的第20輪中看到.NET5.0。當?shù)?0輪最終確定并發(fā)布時,新的排名將是值得關(guān)注的。
    在.NET5.0中的改進是許多人共同努力的結(jié)果,他們在GitHub上,在世界各地,在多個時區(qū)協(xié)同工作。感謝為這一版本做出貢獻的每一個人。別擔心,有很多機會可以貢獻自己的力量。NET5.0版本已經(jīng)結(jié)束,但是下一個版本已經(jīng)開始了。

    Net 5.0是另一個大版本,它應該會改進你使用.NET的許多方面。我們已經(jīng)實現(xiàn)了一系列的改進,從單文件應用程序到性能,從Json序列化的可用性到ARM64的支持。雖然今天可能是您使用.NET5.0的第一天,但我們在微軟的產(chǎn)品中運行.NET5.0已經(jīng)有幾個月了。我們相信,它已準備好供您使用、運營您的業(yè)務(wù)并為您的應用程序提供動力。C#9和F#5中的新語言改進應該會使您的代碼更具表現(xiàn)力,更易于編寫。對于您現(xiàn)有的應用程序來說,.Net 5.0也是一個很好的選擇。在許多情況下,您可以毫不費力地升級。
    如果您對性能感興趣,您可能會對我們在TechEmpower基準測試方面的進展感興趣。回過頭來看,您可以看到.NETCore3.1在最新一輪第19輪中的表現(xiàn)相當不錯。我們期待著在即將到來的第20輪中看到.NET5.0。當?shù)?0輪最終確定并發(fā)布時,新的排名將是值得關(guān)注的。
    在.NET5.0中的改進是許多人共同努力的結(jié)果,他們在GitHub上,在世界各地,在多個時區(qū)協(xié)同工作。感謝為這一版本做出貢獻的每一個人。別擔心,有很多機會可以貢獻自己的力量。NET5.0版本已經(jīng)結(jié)束,但是下一個版本已經(jīng)開始了。



    原文地址:https://www.cnblogs.com/powertoolsteam/p/dotnet5.html

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有