.NET 6新增的20个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);
    }
}

到此这篇关于.NET 6新增的20个API介绍的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • .NET6自定义WebAPI过滤器

    1.上代码 /// <summary> /// API白名单过滤器 /// </summary> public class APIFilter : ActionFilterAttribute { /// <summary> /// 控制器中加了该属性的方法中代码执行之前该方法. /// 所以可以用做权限校验. /// </summary> /// <param name="context"></param> pub

  • 使用.NET6实现动态API

    目录 开发环境 项目地址 项目目标 编码约定 核心代码 使用示例 ApiLite是基于.NET6直接将Service层生成动态api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量. 开发环境 .NET SDK 6.0.100-rc.2.21505.57 VS2022 Preview 7.0 项目地址 GitHub: https://github.com/known/ApiLite 项目目标 根据Service动态生成api 支持自定义路由模板(通

  • 使用.Net6中的WebApplication打造最小API

    .net6在preview4时给我们带来了一个新的API:WebApplication,通过这个API我们可以打造更小的轻量级API服务.今天我们来尝试一下如何使用WebApplication设计一个小型API服务系统. 环境准备 .NETSDK v6.0.0-preview.5.21355.2 Visual Studio 2022 Preview 首先看看原始版本的WebApplication,官方已经提供了样例模板,打开我们的vs2022,选择新建项目选择asp.net core empty

  • 简单聊下.NET6 Minimal API的使用方式

    目录 前言 使用方式 几行代码构建Web程序 更改监听地址 日志操作 基础环境配置 主机相关设置 默认容器替换 中间件相关 请求处理 路由约束 模型绑定 绑定示例 自定义绑定 总结 前言 随着.Net6的发布,微软也改进了对之前ASP.NET Core构建方式,使用了新的Minimal API模式.之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在Minimal API模式下你只需要简单的写几行代码就可以构建一个ASP.NET Core的Web应用,真可谓非常的简单,加之配合c

  • .NET6在WebApi中使用日志组件log4net

    目录 1.安装依赖 2.配置文件 3.注册组件 4.使用 1.安装依赖 Microsoft.Extensions.Logging.Log4Net.AspNetCore 2.配置文件 <?xml version="1.0" encoding="utf-8" ?> <configuration> <!-- This section contains the log4net configuration settings --> <

  • .NET 6新增的20个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 = Date

  • tensorflow常用函数API介绍

    摘要:本文介绍了tensorflow的常用函数. 1.tensorflow常用函数 TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU.一般你不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测.如果检测到 GPU, TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作. 并行计算能让代价大的算法计算加速执行,TensorFlow也在实现上对复杂操作进行了有效的改进.大部分核相关的操作都是设 备相关的

  • es6系列教程_ Map详解以及常用api介绍

    ECMAScript 6中的Map类型是一种存储着许多键值对的有序列表.键值对支持所有的数据类型. 键 0 和 '0'会被当做两个不同的键,不会发生强制类型转换. 如何使用Map? let map = new Map(); 常用方法: set( 键,值 ): 添加新的键值对元素 get( 键 ): 获取键对应的值,如果这个值不存在,返回undefined let map = new Map(); map.set( '0', 'ghostwu' ); map.set( 0, 'ghostwu' )

  • Fastjson 常用API介绍及下载地址(推荐)

    Fastjson是一个Java语言编写的高性能功能完善的JSON库.将解析json的性能提升到极致,是目前Java语言中最快的JSON库.Fastjson接口简单易用,已经被广泛使用在缓存序列化.协议交互.Web输出.Android客户端等多种应用场景. GitHub下载地址: https://github.com/alibaba/fastjson 最新发布版本jar包 1.2.23 下载地址: https://search.maven.org/remote_content?g=com.alib

  • Java阻塞队列四组API介绍(小结)

    通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java并发系列之阻塞队列教程.系列文章,欢迎大家从第一篇文章开始看起. 在查看以上七个队列的API的时候,我们可以很明显的看到以下四组API: add()/remove()/remove offer()/poll()/peek() put/take() offer(e,time,unit)/poll(time,unit). 分别对应的是

  • Java 8中的Collectors API介绍

    目录 Stream.Collect() 方法 Collectors Collectors.ToList() Collectors.ToUnmodifiableList() Collectors.ToSet() Collectors.ToUnmodifiableSet() Collectors.ToCollection() Collectors.ToMap() Collectors.ToUnmodifiableMap() Collectors.CollectingAndThen() Collect

  • JAVA Map架构和API介绍

    首先,我们看看Map架构.如上图:Map 是映射接口,Map中存储的内容是键值对(key-value).AbstractMap 是继承于Map的抽象类,它实现了Map中的大部分API.其它Map的实现类可以通过继承AbstractMap来减少重复编码.SortedMap 是继承于Map的接口.SortedMap中的内容是排序的键值对,排序的方法是通过比较器(Comparator).NavigableMap 是继承于SortedMap的接口.相比于SortedMap,NavigableMap有一系

  • ES6新增关键字let和const介绍

    目录 一.let关键字 1.基本语法 2.let和var的区别 2.1.同一作用域内let不能重复定义同一个名称,var可以重复定义 2.2.两者作用域不同 2.3.不存在变量提升 二.const ES6新增加了两个重要的JavaScript关键字:let和const 一.let关键字 let声明的变量只在let命令所在的代码块内有效. 1.基本语法 let a='123' 2.let和var的区别 var也是用来声明变量,let和var有什么区别呢?区别主要是以下三点: 2.1.同一作用域内l

  • ASP.NET Core之Web API介绍

    目录 1.简单介绍 2.自定义格式化(Format) 1.特定格式的操作结果 2.配置格式化程序 3.添加对 XML 格式的支持 4.强制特定格式化 5.响应格式 URL 映射 6.自定义格式化程序 Protocol Buffers (简称 protobuf) 1.简单介绍 ASP.NET Core Web API 是 ASP.NET Core MVC 的一个功能.ASP.NET Core MVC 包含了对 Web API 的支持.可以构建多种客户端的 HTTP 服务.ASP.NET Core

  • 基于SVG的web页面图形绘制API介绍及编程演示

    一:什么是SVG SVG是1999由W3C发布的2D图形描述语言,纯基于XML格式的标记语言,SVG的 全称是可扩展的矢量图形跟传统的Raster方式的图形(JPG, PNG, GIF等)有很大的差 别.SVG是2D图形开发平台,包括两个部分,一个是基于XML语言的数据描述,另 外一部分是可编程的API,其关键特性支持图形,文本,梯度填充,画笔风格,图形 特效滤镜如高斯模糊,会在稍后的代码中演示.同时还支持各种鼠标事件与DOM部 分API.几乎所有的主流浏览器都支持SVG图形格式的现实与绘制,I

随机推荐