3

您所不知的新 .NET 6 API的那些事

 2 years ago
source link: https://segmentfault.com/a/1190000040821569
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

.NET 6 即将推出,接下来的文章中我们将在.NET 和 ASP.NET Core 中分享一些令人惊喜的新 API,它们是由我们出色的 .NET 开发人员社区直接驱动的,让我们开始逐一了解吧!

即将推出:
https://devblogs.microsoft.co...

在 .NET 6 中,有一个新的 API 可以在不使用 FileStream 的情况下读取/写入文件。它还支持分散/聚集 IO(多个缓冲区)和给定文件偏移量的覆盖读取和写入。

using Microsoft.Win32.SafeHandles;
using SafeFileHandle handle = File.OpenHandle("ConsoleApp128.exe");
long length = RandomAccess.GetLength(handle);

Console.WriteLine(length);

进程路径和 ID

有几种新方法可以在不分配新进程对象的情况下访问进程路径和进程 ID:

int pid = Environment.ProcessId;
string path = Environment.ProcessPath;

Console.WriteLine(pid);
Console.WriteLine(path);

CSPNG(密码安全伪随机数生成器)

从 CSPNG(密码安全伪随机数生成器)生成随机数比以往更容易:

// Give me 200 random bytes
byte[] bytes = RandomNumberGenerator.GetBytes(200);

Parallel.ForEachAsync

我们最终添加了 Parallel.ForEachAsync,这是一种调度异步工作的方法,可让您控制并行度:

var urlsToDownload = new [] 
{
    "https://dotnet.microsoft.com",
    "https://www.microsoft.com",
    "https://twitter.com/davidfowl"
};

var client = new HttpClient();

await Parallel.ForEachAsync(urlsToDownload, async (url, token) =>
{
    var targetPath = Path.Combine(Path.GetTempPath(), "http_cache", url);

    HttpResponseMessage response = await client.GetAsync(url);

    if (response.IsSuccessStatusCode)
    {
        using FileStream target = File.OpenWrite(targetPath);

        await response.Content.CopyToAsync(target);
    }
})

配置Helpes

我们添加了一个帮助程序,以便在缺少必需的配置部分时更容易抛出异常:

var configuration = new ConfigurationManager();
var options = new MyOptions();

// This will throw if the section isn't configured
configuration.GetRequiredSection("MyOptions").Bind(options);

class MyOptions
{
    public string? SettingValue { get; set;}
}

还有大量新的 LINQ 方法。在这个版本中它得到了很多人的喜爱。这是将任何 IEnumerable 分块的新Helper:

int chunkNumber = 1;
foreach (int[] chunk in Enumerable.Range(0, 9).Chunk(3))
{
    Console.WriteLine($"Chunk {chunkNumber++}");
    foreach (var item in chunk)
    {
        Console.WriteLine(item);
    }
} 

更多的LINQ

更多 LINQ!现在有 MaxBy 和MinBy 方法:

var people = GetPeople();

var oldest = people.MaxBy(p => p.Age);
var youngest = people.MinBy(p => p.Age);

Console.WriteLine($"The oldest person is {oldest.Age}");
Console.WriteLine($"The youngest person is {youngest.Age}");

public record Person(string Name, int Age);

Power of 2

不要把数学放在你的脑海里?以下是一些使用 Powerof 2 的新Helper:

using System.Numerics;

uint bufferSize = 235;
if (!BitOperations.IsPow2(bufferSize))
{
    bufferSize = BitOperations.RoundUpToPowerOf2(bufferSize);
}

Console.WriteLine(bufferSize);

WaitAsync 改进

现在有一种更简单(并且正确实现)的方法来等待任务异步完成。如果10 秒内未完成,以下代码将放弃await。该操作可能仍在运行!这是用于不可取消的操作!

Task operationTask = SomeLongRunningOperationAsync();

await operationTask.WaitAsync(TimeSpan.FromSeconds(10));

ThrowIfNull

在抛出异常之前不再需要在每个方法中检查 null。它现在只需一行简单的代码。

void DoSomethingUseful(object obj)
{
    ArgumentNullException.ThrowIfNull(obj);
}

使用 NativeMemory

如果您想使用 CAPI 来分配内存,因为您是 l33thacker或需要分配本机内存,那就使用这个吧。别忘了释放!

using System.Runtime.InteropServices;

unsafe
{
    byte* buffer = (byte*)NativeMemory.Alloc(100);

    NativeMemory.Free(buffer);
}

Posix 信号处理

这是关于对 Posix 信号处理的本机支持,我们还在 Windows 上模拟了几个信号。

using System.Runtime.InteropServices;

var tcs = new TaskCompletionSource();

PosixSignalRegistration.Create(PosixSignal.SIGTERM, context =>
{
    Console.WriteLine($"{context.Signal} fired");
    tcs.TrySetResult();
});

await tcs.Task;

新的Metrics API

我们在 .NET 6 中添加了一个基于@opentelemetry 的全新Metrics API。它支持维度,非常高效,并且将为流行的指标接收器提供导出器。

using System.Diagnostics.Metrics;

// This is how you produce metrics

var meter = new Meter("Microsoft.AspNetCore", "v1.0");
Counter<int> counter = meter.CreateCounter<int>("Requests");

var app = WebApplication.Create(args);

app.Use((context, next) =>
{
    counter.Add(1, KeyValuePair.Create<string, object?>("path", context.Request.Path.ToString()));
    return next(context);
});

app.MapGet("/", () => "Hello World");

您甚至可以收听和计量:

var listener = new MeterListener();
listener.InstrumentPublished = (instrument, meterListener) =>
{
    if(instrument.Name == "Requests" && instrument.Meter.Name == "Microsoft.AspNetCore")
    {
        meterListener.EnableMeasurementEvents(instrument, null);
    }
};

listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) =>
{
    Console.WriteLine($"Instrument: {instrument.Name} has recorded the measurement: {measurement}");
});

listener.Start();

现代定时器 API

现代计时器 API(我认为这是 .NET 中的第5 个计时器 API)。它是完全异步的,不会有遇到其他计时器那样的问题,例如对象生命周期问题,没有异步回调等。

var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));

while (await timer.WaitForNextTickAsync())
{
    Console.WriteLine(DateTime.UtcNow);
}

这只是 .NET 6 中新 API 的一小部分示例。有关更多信息,请查看.NET 6 发行说明 API 差异。此外,Stephen也写了一篇关于.NET6 性能改进的精彩博客,因此请务必阅读。最后,不要忘记下载.NET 6 预览版并立即试用新的 API。

.NET 6 发行说明 API 差异:
https://github.com/dotnet/cor...
.NET6 性能改进:
https://devblogs.microsoft.co...
下载 .NET 6 预览版:
https://dotnet.microsoft.com/...


这里有更多微软官方学习资料和技术文档,扫码获取免费版!
内容将会不定期更新哦!
image.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK