.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 уже сегодня.
