برنامه نویسیبرنامه نویسی وب

بیش از 10 API جدید در NET 6.

NET 6. که چند ماهی است منتشر شده است، ویژگی های جدید خوبی را ارائه داده است که باعث بهبود کارایی برنامه های دات نت شده است.

امروز می خواهیم به معرفی 12 مورد از API های جدید دات نت 6 بپردازیم.

DateOnly و TimeOnly

DateOnly و TimeOnly دو نوع جدید هستند که در NET 6. معرفی شده اند. آن‌ها بخشی از تاریخ یا زمان DateTime را نشان می‌دهند.

// public DateOnly(int year, int month, int day)
// public DateOnly(int year, int month, int day, Calendar calendar)
DateOnly dateOnly = new(2021, 9, 25);
Console.WriteLine(dateOnly);
// Output: 25-Sep-21

// public TimeOnly(int hour, int minute)
// public TimeOnly(int hour, int minute, int second)
// public TimeOnly(int hour, int minute, int second, int millisecond)
// public TimeOnly(long ticks)
TimeOnly timeOnly = new(19, 0, 0);
Console.WriteLine(timeOnly);
// Output: 19:00 PM

DateOnly dateOnlyFromDate = DateOnly.FromDateTime(DateTime.Now);
Console.WriteLine(dateOnlyFromDate);
// Output: 23-Sep-21

TimeOnly timeOnlyFromDate = TimeOnly.FromDateTime(DateTime.Now);
Console.WriteLine(timeOnlyFromDate);
// Output: 21:03 PM

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 در هر متد قبل از ارسال یک اکسپشن وجود ندارد.

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

خواندن و نوشتن فایل ها

دات نت 6 یک API سطح پایین جدید برای خواندن و نوشتن فایل ها بدون FileStream معرفی می‌کند. یک نوع جدید، RandomAccess، یک API ای برای خواندن و نوشتن فایل‌ها با یک روش thread-safe ارائه می‌دهد.

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 کاملا ناهمزمان (async) آشنا شوید. به شما این امکان را می‌دهد تا به طور ناهمزمان منتظر تیک های تایمر بمانید. 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
// ...

Configuration Helper جدید

یک helper جدید کانفیگ، GetRequiredSection، به دات نت 6 اضافه شده است. در صورتی که بخش کانفیگ مورد نیاز وجود نداشته باشد، یک اکسپشن ارسال می‌شود.

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; }
}

Native Memory API

دات نت 6 یک API جدید تخصیص حافظه بومی (Native Memory) معرفی می‌کند. نوع جدید 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);
    }*/
}

WaitAsync بر روی تسک ها

می توانید راحت‌تر منتظر بمانید تا تسک به صورت ناهمزمان کامل شود. 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.

CollectionsMarshal.GetValueRefOrNullRef

این مورد یک ref  را برای مقدار struct برمی‌گرداند که می تواند در جای خود آپدیت شود. برای اهداف عمومی نیست، بلکه برای سناریوهایی با پرفرمنس بالا است.

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

دات نت 6 یک ConfigureHostOptions API جدید بر روی IHostBuilder دارد. این مورد راه‌اندازی برنامه را ساده‌تر می‌سازد.

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);
            });
}

Create Async Scope

NET 6. متد جدید CreateAsyncScope را برای ایجاد AsyncServiceScope معرفی می‌کند. متد موجود CreateScope زمانی که سرویس IAsyncDisposable را dispose می‌کنید، یک اکسپشن ارسال می‌کند. 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;
}

جمع بندی

همان‌طور که می‌بینید، دات نت 6 APIهای جدید بی شماری دارد که ما فقط برخی از آن‌ها را معرفی کردیم که هر کدام از آن‌ها در جایگاه خود بسیار سودمند هستند.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

نوشته های مشابه

دکمه بازگشت به بالا