Yazılımcı Topluluğu Tarafından Çok İstenen .Net 6.0 Apileri

Selamlar,

Bu makalede, .Net 6.0  ile hayatımıza katılan, gözden kaçırılabilecek, kod geliştirmeyi kolaylaştırabilecek developer community tarafından çokça istenen Apilerden bahsetmek istiyorum.

FileStream Kullanmadan Dosya Yazma ve Okuma:

Artık, FileStream kullanmadan dosyaların okunması ve yazılması sağlayan yeni düşük seviye bir API var. Ayrıca, multiple buffer I/0 destekleyip, belirli bir dosya ofsetinde örtüşen okuma ve yazma işlemlerini yapabilmektedir.

Aşağıdaki örnekde “SqlScripts.txt” dosyası byte[ ] dizi olarak okunmuş ve ekrana string olarak basılmıştır.

  • SafeFileHandle handle: Okunacak dosyanın atandığı handel.
  • RandomAccess.GetLength(): İlgili dosyanın boyutu alınır.
  • RandomAccess.Read(handle, buffer,0): Ilgili dosya okunup byte [ ] dizisi olarak buffer değişkenine atanır.
  • Encoding.Default.GetString(buffer): Okunan byte [ ] dizisi string’e çevrilip ekrana basılır.

Örnek Ekran Görüntüsü:

Process Path Ve Uygulamanın PID’sini Alma:

Artık, Enviroment sınıfı altında, uygulama path’i ve PID nosu aşağıdaki gibi alınabilir. Özellikle PID’ye bu kadar rahat erişim, monitoring işlerinde kolaylık sağlıyacaktır. Çünkü ister Windows, ister Linux ister ise OSX olsun, crash olan veya her türlü monitoring yapılacak uygulama, PID numarasından kolaylıkla erişilebilir.

Örnek Ekran Görüntüsü:

Parallel.ForEachAsync :

Öncelikle, bu en sevdiğim yeniliklerden biri oldu. Örneğin 3 farklı kullanıcının repolarını github’dan parallel çekelim.

Örnek bir kullanıcının Repo Url’i bu şekildedir => “https://api.github.com/users/borakasmer/repos” . Aşağıda görüldüğü üzere, geri dönülen birçok node’dan sadece biri gösterilmiştir.(Her bir node, Githubdaki 1 repo’ya karşılık gelmektedir.)

Şimdi yukarıdaki alanların bir kısmına karşılık gelecek, Record Modelleri oluşturalım.

Owner / GitHubRepo Records: Aşağıda görüldüğü gibi Client’ın Repo “adı“, “url“‘i ve “id“‘si alınırken, owner node’u altında “login” ile, client’ın adı alınacaktır. Yani “Owner”, GithubRepo’nun child record’udur. Recordlar ile alakalı detaylı yazıya buradan erişebilirsiniz.

İhtiyaç duyulan kütüphaneler, using ile başta aşağıdaki gibi tanımlanmıştır. Repoları Listelenecek kullanıcı listesi, Urlleri ile “userHandlers” altında toplanmıştır. Ayrıca HttpClient, Github Base Url ile oluşturulmuştur.(https://api.github.com)

  • Aşağıda görüldüğü gibi github’da request limite takılmamak için, Header’a “Authorization” eklenip value olarak Github Token verilebilir. Bu durumda saatlik yaklaşık 5000 request izniniz olmaktadır.
  • Buradaki önemli kısım “MaxDegreeOfParallelism = 3” yani parallel olarak çalıştırılacak Max’imum process 3 olarak atanmasıdır. Yani yukarıda tanımlı 3 user’ın repo bilgileri, parallel ve asenkron olarak çekilecektir.

Aşağıda görüldüğü gibi “userHandlers” içindeki 3 kullanıcı içinde asenkron “Parallel.ForEachAsync()” çalıştırılmıştır.

  • “userHandlers”: Yukarıda tanımlanan request çekilecek Repo Urlleridir.
  • “parallelOptions”: Yine yukarıda tanımlanan Maxiumum çalışacak parallel işlem sayısını tanılamaktadır.
  • “var repos = await client.GetFromJsonAsync<List<GitHubRepo>>(uri, token)”: Herbir kullanıcının Repo Listesi => List<GitHubRepo> model tipine çekilmiştir.
  • “foreach (var repo in repos.Take(2))”: Çekilen tüm Repo Listesi içinden sadece 2 tanesi alınmıştır.
  • “Console.WriteLine($”Repo owner: {repo.owner.Login}\nRepo Name: {repo.name}\nRepo Url: {repo.full_name}\n”)”: Kullanıcının Adı, Repo Adı ve Url bilgisi, konsol’a basılmıştır.

Aşağıdaki sonuç ekranına dikkat ederseniz, sonuç listesi karışık gelmektedir. Çünkü Parallel çalışan Taskların, hangisinin önce biteceği belli olmamaktadır.

Uygulamayı her çalıştırmada, karşımıza farklı bir sıralama şekli gelecektir.

Peki “MaxDegreeOfParallelism = 1” olarak atanır ise ne olur ? Her bir client, tek tek çalıştırılır. Ve böylece Parallel bir durum ortada kalmaz. Bu sefer dönen sonuçlar, aşağıdaki gibi olur. Yani sonuç listesi, userHandlers’e eklenen kullanıcı sırasından başka birşey olmaz. Çünkü her bir user, tek tek senkron çalıştırılır.

Tüm Parallel.ForEachAsync Api Kodları:

RandomNumberGenerator (Security.Cryptography):

Artık random byte dizisi üretmek, bu kadar kolay :) Dikkat ederseniz, RandomNumberGenerator ile yeni bir instance üretmeden kolayca yeni bir sayı oluşturabilirsiniz.

Bu da bellirli iki sayı aralığında random int bir sayı üretme örneğidir.

LINQ Chunk:

IEnumerable’lara gelen “Chunk” helper’ı, bir diziyi guruplamaya yarar. Bence ilerde paginig için gayet yararlı olabilir

Aşağıda görüldüğü gibi array’i, 3 elemanlı diziler halinde 4 alt diziye ayırmıştır. Doğal olarak son dizinin eleman sayısı 1’dir.

Aşağıdaki örnekte AdminUser Record Listesi, “Users.Chunk(2)” ile 2 gruba ayrılmıştır.

Linq ile gelen diğer UnionBy, DistinctBy, MaxBy, MinBy gibi yeniliklerden bu makalemde detaylıca bahsettim.

WaitAsync Geliştirmesi:

Aşağıdaki örnekde  bize asenkron bir Task’ı beklemenin pratik bir yolu gösterilmştir. “WaitAsync(TimeSpan.FromSeconds(5))” ile eğer 5 sn içinde okuma işlemi bitmez ise, koda devem edecektir.

Not: Timeout süresinden sonra, asenkron çalışan kod cancel olmayacak ve arkada çalışmaya devam edecektir. Sadece, biz artık onun çalışmasını sonlandırmasını beklemeyeceğiz.

ThrowIfNull:

Aşağıda görüldüğü gibi null kontorlünü artık tek bir satır ile yapabilmektedir! .Net 7.0 ile bunun daha da pratikleşeceğini söyliyebilirim.

Timer Api (PeriodicTimer):

Aşağıda görüldüğü gibi 5 sn çalışıp iptal edilen yeni bir timer örneği gösterilmiştir. PeriodicTimer’ın avantajı herhangi bir callback’e ihtiyaç duymaması ve “while” içerisinde herbir tick sırasında istenen kodun rahatça çalıştırılabilmesidir. While her saniye değil, tanımlanan bekleme süresinde bir döngüye girecektir. Aşağıdaki örnekde bu süre 1sn’dir.

Bir diğer önemli konu da art arda çalışma sırasında:

  • “var timer = new PeriodicTimer(TimeSpan.FromSeconds(1))” : Her saniye çalışacak şekilde bir interval ayarlanmıştır.
  • CancellationTokenSource _cts = new()“: 5sn sonra iptal etme amaçlı, “Cancellation Token” oluşturulmuştur.
  • try{} catch{}“: 5 sn içinde Token expire edildiği için, hataya düşülmektedir.
  • int dice = RandomNumberGenerator.GetInt32(1, 6)“: 1’den 6’ya kadar bir zar değeri random olarak alınmaktadır.
  • Console.WriteLine($”Dice: {dice} Time: {DateTime.UtcNow}”)“: Console’a o anki saat ve zar değeri basılmaktadır.
  • if ((DateTime.Now – now).TotalSeconds > 5) { StopAsync(); }” Eğer başlangıçtan beri 5sn geçmiş ise, “StopAsync()”methodu çağrılmıştır.
  • async Task StopAsync() { _cts.Cancel(); _cts.Dispose(); }“: 5sn sonra başta tanımlanan CancellationToken dispose edilerek hataya düşülecek, ve timer’ın durması sağlanacaktır.

Geldik bir makalenin daha sonuna. Bu makalede .Net 6.0 ile gelen, gözümüzden kaça bilecek birkaç güzel yenilik ve kolaylıktan bahsetmek istedim. Yeni bir makalede görüşmek üzere hepinize hoşçakalın.

Source:

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir