.NET?6新增的20個(gè)API介紹
DateOnly & TimeOnly
.NET 6 引入了兩種期待已久的類型 - DateOnly 和 TimeOnly, 它們分別代表DateTime的日期和時(shí)間部分。
DateOnly dateOnly = new(2021, 9, 25); Console.WriteLine(dateOnly); TimeOnly timeOnly = new(19, 0, 0); Console.WriteLine(timeOnly); DateOnly dateOnlyFromDate = DateOnly.FromDateTime(DateTime.Now); Console.WriteLine(dateOnlyFromDate); TimeOnly timeOnlyFromDate = TimeOnly.FromDateTime(DateTime.Now); Console.WriteLine(timeOnlyFromDate);
Parallel.ForEachAsync
它可以控制多個(gè)異步任務(wù)的并行度。
var userHandlers = new[] { "users/okyrylchuk", "users/jaredpar", "users/davidfowl" }; using HttpClient client = new() { BaseAddress = new Uri("https://api.github.com"), }; client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("DotNet", "6")); ParallelOptions options = new() { MaxDegreeOfParallelism = 3 }; await Parallel.ForEachAsync(userHandlers, options, async (uri, token) => { var user = await client.GetFromJsonAsync<GitHubUser>(uri, token); Console.WriteLine($"Name: {user.Name}\nBio: {user.Bio}\n"); }); public class GitHubUser { public string Name { get; set; } public string Bio { get; set; } } // Output: // Name: David Fowler // Bio: Partner Software Architect at Microsoft on the ASP.NET team, Creator of SignalR // // Name: Oleg Kyrylchuk // Bio: Software developer | Dotnet | C# | Azure // // Name: Jared Parsons // Bio: Developer on the C# compiler
ArgumentNullException.ThrowIfNull()
ArgumentNullException 的小改進(jìn), 在拋出異常之前不需要在每個(gè)方法中檢查 null, 現(xiàn)在只需要寫一行, 和 response.EnsureSuccessStatusCode();
類似。
ExampleMethod(null); void ExampleMethod(object param) { ArgumentNullException.ThrowIfNull(param); // Do something }
PriorityQueue
.NET 6 新增的數(shù)據(jù)結(jié)構(gòu), PriorityQueue, 隊(duì)列每個(gè)元素都有一個(gè)關(guān)聯(lián)的優(yōu)先級,它決定了出隊(duì)順序, 編號小的元素優(yōu)先出列。
PriorityQueue<string, int> priorityQueue = new(); priorityQueue.Enqueue("Second", 2); priorityQueue.Enqueue("Fourth", 4); priorityQueue.Enqueue("Third 1", 3); priorityQueue.Enqueue("Third 2", 3); priorityQueue.Enqueue("First", 1); while (priorityQueue.Count > 0) { string item = priorityQueue.Dequeue(); Console.WriteLine(item); } // Output: // First // Second // Third 2 // Third 1 // Fourth
RandomAccess
提供基于偏移量的 API,用于以線程安全的方式讀取和寫入文件。
using SafeFileHandle handle = File.OpenHandle("file.txt", access: FileAccess.ReadWrite); // Write to file byte[] strBytes = Encoding.UTF8.GetBytes("Hello world"); ReadOnlyMemory<byte> buffer1 = new(strBytes); await RandomAccess.WriteAsync(handle, buffer1, 0); // Get file length long length = RandomAccess.GetLength(handle); // Read from file Memory<byte> buffer2 = new(new byte[length]); await RandomAccess.ReadAsync(handle, buffer2, 0); string content = Encoding.UTF8.GetString(buffer2.ToArray()); Console.WriteLine(content); // Hello world
PeriodicTimer
認(rèn)識一個(gè)完全異步的“PeriodicTimer”, 更適合在異步場景中使用, 它有一個(gè)方法 WaitForNextTickAsync
。
// One constructor: public PeriodicTimer(TimeSpan period) using PeriodicTimer timer = new(TimeSpan.FromSeconds(1)); while (await timer.WaitForNextTickAsync()) { Console.WriteLine(DateTime.UtcNow); } // Output: // 13 - Oct - 21 19:58:05 PM // 13 - Oct - 21 19:58:06 PM // 13 - Oct - 21 19:58:07 PM // 13 - Oct - 21 19:58:08 PM // 13 - Oct - 21 19:58:09 PM // 13 - Oct - 21 19:58:10 PM // 13 - Oct - 21 19:58:11 PM // 13 - Oct - 21 19:58:12 PM // ...
Metrics API
.NET 6 實(shí)現(xiàn)了 OpenTelemetry Metrics API 規(guī)范, 內(nèi)置了指標(biāo)API, 通過 Meter 類創(chuàng)建下面的指標(biāo)
- Counter
- Histogram
- ObservableCounter
- ObservableGauge
使用的方法如下:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); // Create Meter var meter = new Meter("MetricsApp", "v1.0"); // Create counter Counter<int> counter = meter.CreateCounter<int>("Requests"); app.Use((context, next) => { // Record the value of measurement counter.Add(1); return next(context); }); app.MapGet("/", () => "Hello World"); StartMeterListener(); app.Run(); // Create and start Meter Listener void StartMeterListener() { var listener = new MeterListener(); listener.InstrumentPublished = (instrument, meterListener) => { if (instrument.Name == "Requests" && instrument.Meter.Name == "MetricsApp") { // Start listening to a specific measurement recording meterListener.EnableMeasurementEvents(instrument, null); } }; listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) => { Console.WriteLine($"Instrument {instrument.Name} has recorded the measurement: {measurement}"); }); listener.Start(); }
檢查元素是否可為空的反射API
它提供來自反射成員的可空性信息和上下文:
- ParameterInfo 參數(shù)
- FieldInfo 字段
- PropertyInfo 屬性
- EventInfo 事件
var example = new Example(); var nullabilityInfoContext = new NullabilityInfoContext(); foreach (var propertyInfo in example.GetType().GetProperties()) { var nullabilityInfo = nullabilityInfoContext.Create(propertyInfo); Console.WriteLine($"{propertyInfo.Name} property is {nullabilityInfo.WriteState}"); } // Output: // Name property is Nullable // Value property is NotNull class Example { public string? Name { get; set; } public string Value { get; set; } }
檢查嵌套元素是否可為空的反射API
它允許您獲取嵌套元素的可為空的信息, 您可以指定數(shù)組屬性必須為非空,但元素可以為空,反之亦然。
Type exampleType = typeof(Example); PropertyInfo notNullableArrayPI = exampleType.GetProperty(nameof(Example.NotNullableArray)); PropertyInfo nullableArrayPI = exampleType.GetProperty(nameof(Example.NullableArray)); NullabilityInfoContext nullabilityInfoContext = new(); NullabilityInfo notNullableArrayNI = nullabilityInfoContext.Create(notNullableArrayPI); Console.WriteLine(notNullableArrayNI.ReadState); // NotNull Console.WriteLine(notNullableArrayNI.ElementType.ReadState); // Nullable NullabilityInfo nullableArrayNI = nullabilityInfoContext.Create(nullableArrayPI); Console.WriteLine(nullableArrayNI.ReadState); // Nullable Console.WriteLine(nullableArrayNI.ElementType.ReadState); // Nullable class Example { public string?[] NotNullableArray { get; set; } public string?[]? NullableArray { get; set; } }
ProcessId & ProcessPath
直接通過 Environment 獲取進(jìn)程ID和路徑。
int processId = Environment.ProcessId string path = Environment.ProcessPath; Console.WriteLine(processId); Console.WriteLine(path);
Configuration 新增 GetRequiredSection()
和 DI 的 GetRequiredService() 是一樣的, 如果缺失, 則會拋出異常。
WebApplicationBuilder builder = WebApplication.CreateBuilder(args); WebApplication app = builder.Build(); MySettings mySettings = new(); // Throws InvalidOperationException if a required section of configuration is missing app.Configuration.GetRequiredSection("MySettings").Bind(mySettings); app.Run(); class MySettings { public string? SettingValue { get; set; } }
CSPNG 密碼安全偽隨機(jī)數(shù)生成器
您可以從密碼安全偽隨機(jī)數(shù)生成器 (CSPNG) 輕松生成隨機(jī)值序列。
它對于以下場景中很有用:
密鑰生成
隨機(jī)數(shù)
某些簽名方案中的鹽
// Fills an array of 300 bytes with a cryptographically strong random sequence of values. // GetBytes(byte[] data); // GetBytes(byte[] data, int offset, int count) // GetBytes(int count) // GetBytes(Span<byte> data) byte[] bytes = RandomNumberGenerator.GetBytes(300);
Native Memory API
.NET 6 引入了一個(gè)新的 API 來分配本機(jī)內(nèi)存, NativeMemory 有分配和釋放內(nèi)存的方法。
unsafe { byte* buffer = (byte*)NativeMemory.Alloc(100); NativeMemory.Free(buffer); /* This class contains methods that are mainly used to manage native memory. public static class NativeMemory { public unsafe static void* AlignedAlloc(nuint byteCount, nuint alignment); public unsafe static void AlignedFree(void* ptr); public unsafe static void* AlignedRealloc(void* ptr, nuint byteCount, nuint alignment); public unsafe static void* Alloc(nuint byteCount); public unsafe static void* Alloc(nuint elementCount, nuint elementSize); public unsafe static void* AllocZeroed(nuint byteCount); public unsafe static void* AllocZeroed(nuint elementCount, nuint elementSize); public unsafe static void Free(void* ptr); public unsafe static void* Realloc(void* ptr, nuint byteCount); }*/ }
Power of 2
.NET 6 引入了用于處理 2 的冪的新方法。
- 'IsPow2' 判斷指定值是否為 2 的冪。
- 'RoundUpToPowerOf2' 將指定值四舍五入到 2 的冪。
// IsPow2 evaluates whether the specified Int32 value is a power of two. Console.WriteLine(BitOperations.IsPow2(128)); // True // RoundUpToPowerOf2 rounds the specified T:System.UInt32 value up to a power of two. Console.WriteLine(BitOperations.RoundUpToPowerOf2(200)); // 256
WaitAsync on Task
您可以更輕松地等待異步任務(wù)執(zhí)行, 如果超時(shí)會拋出 “TimeoutException”
Task operationTask = DoSomethingLongAsync(); await operationTask.WaitAsync(TimeSpan.FromSeconds(5)); async Task DoSomethingLongAsync() { Console.WriteLine("DoSomethingLongAsync started."); await Task.Delay(TimeSpan.FromSeconds(10)); Console.WriteLine("DoSomethingLongAsync ended."); } // Output: // DoSomethingLongAsync started. // Unhandled exception.System.TimeoutException: The operation has timed out.
新的數(shù)學(xué)API
新方法:
- SinCos
- ReciprocalEstimate
- ReciprocalSqrtEstimate
新的重載:
- Min, Max, Abs, Sign, Clamp 支持 nint 和 nuint
- DivRem 返回一個(gè)元組, 包括商和余數(shù)。
// New methods SinCos, ReciprocalEstimate and ReciprocalSqrtEstimate // Simultaneously computes Sin and Cos (double sin, double cos) = Math.SinCos(1.57); Console.WriteLine($"Sin = {sin}\nCos = {cos}"); // Computes an approximate of 1 / x double recEst = Math.ReciprocalEstimate(5); Console.WriteLine($"Reciprocal estimate = {recEst}"); // Computes an approximate of 1 / Sqrt(x) double recSqrtEst = Math.ReciprocalSqrtEstimate(5); Console.WriteLine($"Reciprocal sqrt estimate = {recSqrtEst}"); // New overloads // Min, Max, Abs, Clamp and Sign supports nint and nuint (nint a, nint b) = (5, 10); nint min = Math.Min(a, b); nint max = Math.Max(a, b); nint abs = Math.Abs(a); nint clamp = Math.Clamp(abs, min, max); nint sign = Math.Sign(a); Console.WriteLine($"Min = {min}\nMax = {max}\nAbs = {abs}"); Console.WriteLine($"Clamp = {clamp}\nSign = {sign}"); // DivRem variants return a tuple (int quotient, int remainder) = Math.DivRem(2, 7); Console.WriteLine($"Quotient = {quotient}\nRemainder = {remainder}"); // Output: // Sin = 0.9999996829318346 // Cos = 0.0007963267107331026 // Reciprocal estimate = 0.2 // Reciprocal sqrt estimate = 0.4472135954999579 // Min = 5 // Max = 10 // Abs = 5 // Clamp = 5 // Sign = 1 // Quotient = 0 // Remainder = 2
CollectionsMarshal.GetValueRefOrNullRef
這個(gè)是在字典中循環(huán)或者修改結(jié)可變結(jié)構(gòu)體時(shí)用, 可以減少結(jié)構(gòu)的副本復(fù)制, 也可以避免字典重復(fù)進(jìn)行哈希計(jì)算,這個(gè)有點(diǎn)晦澀難懂,有興趣的可以看看這個(gè)
https://github.com/dotnet/runtime/issues/27062
Dictionary<int, MyStruct> dictionary = new() { { 1, new MyStruct { Count = 100 } } }; int key = 1; ref MyStruct value = ref CollectionsMarshal.GetValueRefOrNullRef(dictionary, key); // Returns Unsafe.NullRef<TValue>() if it doesn't exist; check using Unsafe.IsNullRef(ref value) if (!Unsafe.IsNullRef(ref value)) { Console.WriteLine(value.Count); // Output: 100 // Mutate in-place value.Count++; Console.WriteLine(value.Count); // Output: 101 } struct MyStruct { public int Count { get; set; } }
ConfigureHostOptions
IHostBuilder 上的新 ConfigureHostOptions API, 可以更簡單的配置應(yīng)用。
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureHostOptions(o => { o.ShutdownTimeout = TimeSpan.FromMinutes(10); }); }
Async Scope
.NET 6 引入了一種新的CreateAsyncScope方法, 當(dāng)您處理 IAsyncDisposable 的服務(wù)時(shí)現(xiàn)有的CreateScope方法會引發(fā)異常, 使用 CreateAsyncScope 可以完美解決。
await using var provider = new ServiceCollection() .AddScoped<Example>() .BuildServiceProvider(); await using (var scope = provider.CreateAsyncScope()) { var example = scope.ServiceProvider.GetRequiredService<Example>(); } class Example : IAsyncDisposable { public ValueTask DisposeAsync() => default; }
加密類簡化
- DecryptCbc
- DecryptCfb
- DecryptEcb
- EncryptCbc
- EncryptCfb
- EncryptEcb
static byte[] Decrypt(byte[] key, byte[] iv, byte[] ciphertext) { using (Aes aes = Aes.Create()) { aes.Key = key; return aes.DecryptCbc(ciphertext, iv, PaddingMode.PKCS7); } }
到此這篇關(guān)于.NET 6新增的20個(gè)API介紹的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
.Net結(jié)構(gòu)型設(shè)計(jì)模式之享元模式(Flyweight)
這篇文章介紹了.Net結(jié)構(gòu)型設(shè)計(jì)模式之享元模式(Flyweight),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05ASP.NET中 RadioButtonList 單選按鈕組控件的使用方法
本文主要簡單介紹RadioButtonList控件的常見屬性和使用方法,希望對大家有所幫助。2016-04-04asp.net平臺下C#實(shí)現(xiàn)Socket通信
這篇文章介紹了asp.net平臺下C#實(shí)現(xiàn)Socket通信的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01ASP.NET web.config 配置節(jié)點(diǎn)詳解
這篇文章主要介紹了ASP.NET web.config 節(jié)點(diǎn)的配置,講解的非常詳細(xì),需要的朋友可以參考下。2016-06-06利用C#遠(yuǎn)程存取Access數(shù)據(jù)庫
目前,基于數(shù)據(jù)庫服務(wù)器的桌面管理程序和Web程序已經(jīng)有太多的應(yīng)用了,尤其是網(wǎng)絡(luò)的大量普及,孤立地?cái)?shù)據(jù)庫管理系統(tǒng)無法勝任分布式管理應(yīng)用,但是面對基于Access數(shù)據(jù)庫的現(xiàn)有的桌面應(yīng)用我們也無法完全的摒棄。我們利用.Net 遠(yuǎn)程處理功能將連接和存取Access的行為封裝為一個(gè)遠(yuǎn)程對象,供網(wǎng)絡(luò)中其它客戶端通過調(diào)用該遠(yuǎn)程對象來存取實(shí)際的Access數(shù)據(jù)庫。我們以 C# 2005 為開發(fā)語言來實(shí)現(xiàn)上述功能。2008-04-04.Net結(jié)構(gòu)型設(shè)計(jì)模式之適配器模式(Adapter)
這篇文章介紹了.Net結(jié)構(gòu)型設(shè)計(jì)模式之適配器模式(Adapter),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05SQL Server 2005安裝過程中出現(xiàn)錯(cuò)誤的解決辦法
SQL Server 2005安裝過程中出現(xiàn)錯(cuò)誤的解決辦法...2007-02-02