.NET 6 в процессе разработки, и я хотел поделиться некоторыми из моих любимых новых API в .NET и ASP.NET Core, которые вам обязательно понравятся. Почему они понравятся? Потому что они разработаны при прямом участии нашего фантастического сообщества разработчиков .NET. Подробнее в статье.
Чтение и запись файлов
В .NET 6 появился новый низкоуровневый API, позволяющий читать/записывать файлы без использования FileStream. Он также поддерживает scatter/gather IO (несколько буферов) и дублирующиеся чтение и запись при заданном смещении файла (file offset).
using Microsoft.Win32.SafeHandles;
using SafeFileHandle handle = File.OpenHandle("ConsoleApp128.exe");
long length = RandomAccess.GetLength(handle);
Console.WriteLine(length);
Путь и идентификатор процесса
Есть несколько новых способов доступа к пути и идентификатору процесса без выделения нового объекта процесса:
int pid = Environment.ProcessId;
string path = Environment.ProcessPath;
Console.WriteLine(pid);
Console.WriteLine(path);
CSPNG (криптографически безопасный генератор псевдослучайных чисел)
Генерация случайных чисел из CSPNG (криптографически безопасного генератора псевдослучайных чисел) стала проще, чем когда-либо:
// Дай мне 200 случайных 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);
}
Помощники по настройке
Мы добавили помощник, чтобы упростить сброс, если отсутствует требуемый раздел конфигурации:
var configuration = new ConfigurationManager();
var options = new MyOptions();
configuration.GetRequiredSection("MyOptions").Bind(options);
class MyOptions
{
public string? SettingValue { get; set;}
LINQ
Также есть масса новых методов LINQ. Вот новый помощник для разбиения любого IEnumerable на пакеты:
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);
Вторая степень
Не держите математику в голове? И я нет. Вот несколько новых помощников для работы со второй степенью:
using System.Numerics;
uint bufferSize = 235;
if (!BitOperations.IsPow2(bufferSize))
{
bufferSize = BitOperations.RoundUpToPowerOf2(bufferSize);
}
Console.WriteLine(bufferSize);
Улучшения WaitAsync
Теперь существует гораздо более простой (и правильно реализованный) способ ожидания асинхронного завершения задачи. Следующий код вернет await, если он не был завершен в течение 10 секунд. Операция может еще продолжаться. Это для неотменяемых операций.
Task operationTask = SomeLongRunningOperationAsync();
await operationTask.WaitAsync(TimeSpan.FromSeconds(10));
ThrowIfNull
Больше не нужно проверять значение null в каждом методе перед тем, как сбросить исключение. Теперь это всего лишь одна строка кода.
void DoSomethingUseful(object obj)
{
ArgumentNullException.ThrowIfNull(obj);
}
Работа с NativeMemory
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;
Новый API метрик
Мы добавили совершенно новый API метрик, основанный на @opentelemetry в .NET 6. Он поддерживает измерения, суперэффективен и будет иметь экспортеры для популярных сервисов метрик.
using System.Diagnostics.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");
Вы даже можете listen и meter:
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 таймера (я думаю, что это уже пятый API таймера в .NET). Он полностью асинхронен и не подвержен типам ошибок, с которыми сталкиваются другие таймеры, например, проблемами времени жизни объекта, отсутствием асинхронных обратных вызовов и т.д.
var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync())
{
Console.WriteLine(DateTime.UtcNow);
}
Summary
Это всего лишь несколько примеров новых API, которые появятся в .NET 6. Для получения дополнительной информации см. Различия API, примечаний к выпуску .NET 6. Кроме того, Стивен только что написал впечатляющий пост об улучшении производительности в .NET6, так что обязательно прочтите его. Наконец, не забудьте скачать предварительную версию .NET 6 и опробовать новые API уже сегодня.