20 个 .NET 6 新增的 API
DateOnly & TimeOnly
.NET 6 引入了两种期待已久的类型 - DateOnly 和 TimeOnly, 它们分别代表DateTime的日期和时间部分。
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
它可以控制多个异步任务的并行度。
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 的小改进, 在抛出异常之前不需要在每个方法中检查 null, 现在只需要写一行,  和 response.EnsureSuccessStatusCode(); 类似。
ExampleMethod(null);
void ExampleMethod(object param)
{
    ArgumentNullException.ThrowIfNull(param);
    // Do something
}
PriorityQueue
.NET 6 新增的数据结构, PriorityQueue, 队列每个元素都有一个关联的优先级,它决定了出队顺序, 编号小的元素优先出列。
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
认识一个完全异步的“PeriodicTimer”, 更适合在异步场景中使用, 它有一个方法 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 实现了 OpenTelemetry Metrics API 规范, 内置了指标API, 通过 Meter 类创建下面的指标
- 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 参数
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
它允许您获取嵌套元素的可为空的信息, 您可以指定数组属性必须为非空,但元素可以为空,反之亦然。
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 获取进程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 密码安全伪随机数生成器
您可以从密码安全伪随机数生成器 (CSPNG) 轻松生成随机值序列。
它对于以下场景中很有用:
- 密钥生成
 - 随机数
 - 某些签名方案中的盐
 
// 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 引入了一个新的 API 来分配本机内存, NativeMemory 有分配和释放内存的方法。
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
您可以更轻松地等待异步任务执行, 如果超时会抛出 “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.
新的数学API
新方法:
- SinCos
 - ReciprocalEstimate
 - ReciprocalSqrtEstimate
 
新的重载:
- Min, Max, Abs, Sign, Clamp 支持 nint 和 nuint
 - DivRem 返回一个元组, 包括商和余数。
 
// 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
这个是在字典中循环或者修改结可变结构体时用, 可以减少结构的副本复制, 也可以避免字典重复进行哈希计算,这个有点晦涩难懂,有兴趣的可以看看这个
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, 可以更简单的配置应用。
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方法, 当您处理 IAsyncDisposable 的服务时现有的CreateScope方法会引发异常, 使用 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);
    }
}
全文完...
作者: Oleg Kyrylchuk
原文: https://blog.okyrylchuk.dev/

20 个 .NET 6 新增的 API的更多相关文章
- 第30月第11天 Xcode 9.0中新增的API版本检查@available
		
1.Xcode 9.0中新增的API版本检查@available https://www.jianshu.com/p/0a94baa6c3dd https://www.jianshu.com/p/b8 ...
 - freeswitch新增模块API
		
概述 上一章我们讲解了freeswitch的源码基本结构,以及如何新增一个插件式模块. freeswitch的架构非常适合这种业务开发模式,即以freeswitch的基本功能为开发平台,新增插件式模块 ...
 - 腾讯微博java(android)sdk新增微博api详细介绍
		
本文主要介绍腾讯微博android sdk中新增微博有关的8个接口,以及使用的示例代码 注意:以下所有的api示例代码都需要先新建QqTSdkService类对象qqTSdkService并初始化,见 ...
 - css3新增属性API
		
写在前面:由于CSS5标准还未完全订下来,所以各种内核的浏览器都有自己的标准,为了不使属性混淆,所以各家在各自标准前加了一个前缀. -moz- 主要是firefox火狐 -webikt-主要是chr ...
 - ES6深入浅出-11 ES6新增的API(上)-2.Array新增API
		
Array.form 把不是数组的东西变成数组.最常见的就是把伪数组变成数组 那么什么是伪数组 这就是伪数组,因为它不是继承自Array的原型的对象.它只是一个看起来很像数组的数组 只看下面的代码.a ...
 - 对HTML5新增JS Api的思考
		
1.为什么javascript的变量名不使用css中的命名方法,而选择使用驼峰命名法 因为在javascript中“-”表示减法,所以如果使用“-”的话会出现不必要的问题. 2.在javascript ...
 - HTML5学习笔记简明版(11):新增的API
		
HTMLDocument上的扩展 HTML5在DOM Level 2 HTML上扩展了一些HTMLDocument的接口.这些接口在全部实现了Document接口的元素对象上进行了实现. HTML5在 ...
 - ES6深入浅出-12 ES6新增的API(下)-1.录屏
		
String.includes es5里面判断字符串是否存在的方法 search searcg的厉害之处是可以使用正则 match正则的方式 repeat -1遍,就不合法 startsWith 判断 ...
 - ES6深入浅出-11 ES6新增的API(上)-1.Object.assign
		
这些都是es6才有的 Object.assign 在a加上三个属性 分别是p1\p2\p3 以前是这么去加 b的三个属性p1.p2.p3就全部复制到a这个对象上了. 把后面的东西放到前面的东西上 两个 ...
 
随机推荐
- 在Vs code中使用sftp插件以及连接windows远程sftp协议部署指导(解决vscode的sftp插件中文目录乱码问题)
			
一.启动SFtp 二.上手vs code SFTP插件 2.1 初始配置 2.2解决乱码问题 三.SFTP配置 3.1常用配置 3.2示例配置 四.SFTP使用 五.扩展阅读 一.启动SFtp 话说小 ...
 - 你真的懂Redis的5种基本数据结构吗?
			
摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...
 - 14-1-Unsupervised Learning ---dimension reduction
			
无监督学习(Unsupervised Learning)可以分为两种: 化繁为简 聚类(Clustering) 降维(Dimension Reduction) 无中生有(Generation) 所谓的 ...
 - [luogu1390]公约数的和
			
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 2000005 4 long long n,ans,f[N],vi ...
 - [bzoj1071]组队
			
题目即要求$Ah+Bv<=C+Aminh+Bminv$,如果同时枚举minh和minv,那么即要求$minh\le h$,$minv\le v$且$s\le C+Aminh+Bminv$从小到大 ...
 - layui增加转圈效果
			
var loadix = layer.load(1, {shade: [0.1,'#fff']}); layer.close(loadix);
 - CSS Web Fonts 网络字体
			
Fonts 1. CSS font-family 在 CSS 中,可以使用 font-family 属性来指定字体,浏览器渲染文字时候会根据这个属性应用于元素.如果没有指定这个属性或者指定的字体不存在 ...
 - 简单聊下.NET6 Minimal API的使用方式
			
前言 随着.Net6的发布,微软也改进了对之前ASP.NET Core构建方式,使用了新的Minimal API模式.之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在Minimal ...
 - 洛谷 P4002 - [清华集训2017]生成树计数(多项式)
			
题面传送门 神题. 考虑将所有连通块缩成一个点,那么所有连好边的生成树在缩点之后一定是一个 \(n\) 个点的生成树.我们记 \(d_i\) 为第 \(i\) 个连通块缩完点之后的度数 \(-1\), ...
 - Codeforces 730L - Expression Queries(大模拟)
			
Codeforces 题面传送门 & 洛谷题面传送门 大模拟(?)+阿巴细节题,模拟赛时刚了 3h 最后因为某个细节写挂 100->40/ll/ll(下次一定不能再挂分了啊 awa) 首 ...