.NET 11’de Process API’si Neden Bu Kadar Önemli?
Dürüst olmak gerekirse,.NET tarafında yıllardır en çok “idare eder” denilen sınıflardan biri System.Diagnostics.Process öldü. Çalıştırıyorduk, çıkış alıyorduk, bazen de gece yarısı bir pipe doldu diye saç baş yoluyorduk..NET 11 ile gelen yenilikler bana tam olarak şunu hissettirdi: ekip, bu alanı artık yamayla değil, düzgün bir temel atarak toparlamış.
Açık konuşayım; ilk okuduğumda “tamam güzel, ama gerçekten günlük hayatta fark yaratır mı?” diye düşündüm. Sonra sahadaki birkaç senaryoyu aklıma getirdim. Bir finans müşterisinde log toplayan yardımcı servisimiz vardı, başka bir projede Azure DevOps pipeline içinde CLI araçları çalışıyordu, bir başka tarafta da Linux container içinde kısa ömürlü işçiler (ben de ilk duyduğumda şaşırmıştım). İşin aslı şu ki Process API’sindeki küçük gibi görünen değişiklikler, bu tip kurulumlarda bayağı can sıkıcı hataları ortadan kaldırıyor.
Eski sorun neydi, yeni yaklaşım ne getiriyor?
Şöyle söyleyeyim,.NET 10 ve öncesinde süreç yönetimi çoğu zaman biraz ip üstünde yürümek gibiydi. Çıkışı ayrı oku, hatayı ayrı oku, pipe buffer dolmasın diye bekle, çocuk proses ana proses ölünce ortada kalmasın… Bakınca basit dürüyor ama pratikte ince ayar istiyor. Hele bir de stdout ve stderr’i aynı anda okumazsanız klasik deadlock kapınızı çalabiliyordu. Ben bunu 2019’da İstanbul’daki bir üretim ortamında yaşadım; tek satırlık bir komut uzun log basınca worker kilitlendi. O gün öğrendiğim ders hâlâ aklımdadır: proses yönetimi “basit iş” değildir.
.NET 11’de gelen yaklaşım işe daha yüksek seviyeli API’lerle işi kolaylaştırıyor. Bir kere çalıştırıp metin almak isteyen için tek satırlık kullanım var. Hiç çıktı umursamayan için daha hafif yol var. Çocuk prosesin yaşam süresini kontrol etmek isteyen için ayrıca seçenek var. Hani eskiden her şeyi kendiniz bağlamak zorundaydınız ya — şimdi framework biraz sizin yerinize düşünüyor.
Bir de şu var: yalnızca kolaylık değil, mimarı temizlik de geliyor. En çok da trimmer dostu yüzeyler ve SafeProcessHandle tabanlı yapı benim hoşuma gitti. Çünkü NativeAOT veya trim edilen uygulamalarda gereksiz — kendi adıma konuşayım — ağırlık istemiyorsunuz. AZ-305 hazırlığında hep şunu anlatırım: “Bulutta maliyet sadece CPU değil; bakım yükü de maliyet.” Burada da aynı mantık geçerli.
Durun, bir saniye.
Tek satırlık çalıştırma rahatlığı
Process.RunAndCaptureTextAsync gibi API’ler günlük işleri ciddi biçimde sadeleştiriyor. Mesela küçük bir admin aracı yazıyorsanız. Dışarıdaki bir komutun çıktısını anında almak istiyorsanız artık böl böl boilerplate yazmanız gerekmiyor. Bence bu güzel özellik ama henüz ham olduğu hissi yok değil; bazı edge-case’lerde yine test şart.
Geçen ay Ankara’daki bir müşteride PowerShell ile entegrasyon yapan bir yardımcı servis revizyonuna baktık. En büyük kazanç kod kısalığı değildi aslında; hata yüzeyinin azalmasıydı. Daha az satır kod = daha az yanlış redirection = daha az gece alarmı! Basit denklem ama etkisi büyük.
Process yönetiminde asıl fark bazen performans değil, sürprizlerin azalmasıdır.
Deadlock derdi biter mi? Büyük ölçüde evet
Beni en çok ilgilendiren konu bu öldü doğrusu. Yeni ReadAllText, ReadAllBytes, ReadAllLinesAsync gibi API’ler stdout. Stderr’i birlikte okuyarak pipe tıkanmasını önlemeye çalışıyor. Yanı biri doldu da diğeri bekledi gibi klasik kâbus senaryosu azalıyor (ben de ilk duyduğumda şaşırmıştım). E tabi tamamen sihir değil; sız yine de uzun süren işler için timeout ve cancellation koyacaksınız.
Bunu küçük startup ile enterprise arasında şöyle ayırırım: startup ekibindeyseniz genelde hızlı ilerlemek istersiniz. Birkaç CLI aracıyla iş bitirirsiniz; burada yüksek seviyeli API’ler sizi hızlandırır. Enterprise tarafta işe güvenilirlik öncelik olur, çünkü tek bir tıkanma onlarca servisi domino taşı gibi etkileyebilir. Kurumsal müşterilerimde gördüğüm kadarıyla Türkiye’de asıl fark burada çıkıyor — ekip büyüdükçe “çalışıyor” yetmiyor, “izlenebilir ve kontrollü çalışıyor” lazım oluyor.
| Senaryo | .NET 11 Öncesi | .NET 11 Sonrası |
|---|---|---|
| Küçük script/araç | Daha fazla manuel kod | Daha kısa ve temiz kullanım |
| Eşzamanlı çıktı okuma | Deadlock riski daha yüksek | Mux tabanlı okuma ile daha güvenli yapı |
| AOT / trimming | Daha ağır yüzey alanı | Daha hafif handle tabanlı seçenekler |
| Süreç yaşam döngüsü | Kendi başınıza yönetirsiniz | KillOnParentExit, detached seçenekleriyle daha net kontrol |
Kafamı kurcalayan eksik taraflar da var
Şunu söyleyeyim, Burası önemli: Kağıt üstünde süper görünen şeylerin pratikte yan etkisi olabiliyor. Yeni abstractions iyi ama öğrenme eğrisi sıfır değil.
Evet.
Bunu yaşayan biri olarak söyleyeyim, Hele mevcut kod tabanınızda onlarca yerde klasik Process kullanıyorsanız geçiş planı yapmanız gerekir; ben olsam önce kilit olmayan yardımcı servislerde denerdim (biraz risk alıp sonra genişletmek genelde daha sakın ilerletiyor).
Bir ara.NET preview sürümünde benzer bir işlem sırasında yanlış handle inheritance yüzünden beklenmedik davranış görmüştük; çözümü açıkçası uğraştırmıştı.
O yüzden yeni API’lerdeki kontrol artışını seviyorum ama ilk denemede mutlak rahatlık beklemiyorum… yanı biraz test disiplini şart.
Lifetime yönetimi: Çocuk proses meselesi nihayet ciddileşmiş
İlginç olan şu ki, KillOnParentExit. Bağlantılı yaşam döngüsü özellikleri bence kurumsal tarafta en kıymetli parçalardan biri olmuş.
Mesela Windows servislerinde veya Linux daemon benzeri yapılarda ana proses ölürken arkada zombie benzeri şeyler bırakmak istemezsiniz; bu durum sahada bazen fark edilmiyor bile (ta ki ertesi gün sistemde anlamsız kaynak tüketimi görünene kadar…).
Evet.
StartDetached işe tam tersi ihtiyaçlara cevap veriyor: parent kapanınca yaşayan bağımsız süreçler için kullanışlı olabilir.
Mesela uzun sürecek bakım işlemlerini kullanıcı oturumundan koparmak isteyebilirsiniz.
Ama dürüst olayım, bunu her yere yaymak doğru değil; detached süreçler kontrol kaybına da yol açabilir.
Neyse uzatmayalım, burada prensip şu: Eğer süreç sizin hayat döngünüzün parçasıysa bağlayın; gerçekten bağımsız olması gerekiyorsa ayırın ama iz bırakmayı unutmayın (log, telemetry, correlation id). Ben Logosoft tarafında danışmanlık yaparken müşterilere hep bunu söylüyorum: gevşek çalışan sistem hoş görünür. Operasyon ekibi önü sabah çok sevmez!
- |KillOnParentExit:| Ana uygulama giderse çocuk da gitsin istiyorsanız ideal.
- |StartDetached:| Bağımsız kalan job veya utility senaryolarında işe yarar.|/li|
- Userland izleme: Loglama olmadan ikisi de yarım kalır.
AOT ve trimming tarafında niye sevindim?
Bence sessiz ama değerli yeniliklerden biri de düşük seviyeli handle tabanlı API seti öldü: özellikle trimmer-friendly tasarım ciddi avantaj veriyor.
NativeAOT hedefliyorsanız her byte’ın hesabını yapmak gerekiyor; “şu sınıf gelsin bakalım” demek yok artık pek.
.NET ekibinin bu tarafa yatırım yapması doğru yönde atılmış adım gibi dürüyor.
Bunu TL bazında düşününce iş biraz daha anlaşılır oluyor aslında — azalan binary boyutu tek başına para kazandırmaz belki ama container image küçülmesi, pull sürelerinin azalması ve CI/CD hattının hızlanması doğrudan etki ediyor.
Küçük ekipte bu fark idare eder düzeydedir belki; büyük enterprise’da işe build farm üzerindeki baskıyı azaltır.
Tam da öyle.
Evet, doğru duydunuz.
// Mantığı göstermek için basitleştirilmiş örnek
var result = await Process.RunAndCaptureTextAsync(new ProcessStartInfo
{
FileName = "dotnet",
Arguments = "--info"
});
Console.WriteLine(result.StandardOutput);
Console.Error.WriteLine(result.StandardError);
Sahada nasıl kullanırım?
Eğer bugün yeni bir internal tool yazıyor olsaydım üç adımla başlardım : önce çıktı ihtiyacımı netleştirirdim, sonra child process’in yaşam döngüsünü tanımlarım, son olarak handle inheritance’ı minimuma indirirdim. Çünkü sızıntılar genelde oradan çıkıyor — özellikle CI ajanlarında görülüyor bu durum.
Tam burada kişisel kanaatimi söyleyeyim : Eğer bütçeniz kısıtlıysa ya da ekip çok küçükse pek çok yenilikleri aynı anda almaya çalışma yerine en kilit iki alanı seçin — deadlock-free output capture. Lifecycle control yeterince fayda verir ; bileşik hâlde bakınca güçlü oluyorlar.
Ha bu arada otomasyon araçlarınız varsa onları da gözden geçirin ; ben geçen yıl İzmir’deki bir üretici firmada eski batch çağrılarını yenilerken en çok zamanımı alan şey aslında komutun kendisi değil wrapper katmanıydı.
Bu kadar mı?
Şimdi gelelim işin can alıcı noktasına.
. NET tarafında birçok kişi performans deyince sadece algoritmaya bakıyor ama işletim sistemi sınırıyla konuşurken asıl mesele iletişim şekli oluyor yahu… Process API’si tam burada önemlileşiyor işte.
Az önce X dedim ama aslında Y daha doğru olabilir :
buradaki ana konu hızdan çok öngörülebilirlik.
Denemek istiyorsanız ilk iş şunu yapın :
mevcut helper sınıfınızı bulun,
çıktı okumasını eşzamanlı hâle getirin,
sonra timeout/cancellation ekleyin.
Bunları yapmadan production’a atlamayın derim.
Peki neden? (inanın bana)
Sıkça Sorulan Sorular
.NET 11’de Process API’si neden bu kadar önemli?
Şöyle söyleyeyim, Aslında.NET 11 ile birlikte process çalıştırmak hem daha güvenli hem de çok daha sade bir hâl alıyor. Hani özellikle deadlock riskinin azalması. Yaşam döngüsü üzerindeki kontrolün artması günlük işi ciddi anlamda kolaylaştırıyor. Bence kurumsal ortamlarda bu değişiklik doğrudan operasyonel rahatlığa yansıyor.
Yeni API’lere hemen geçmek şart mı?
Tuhaf ama, Hayır, tüm kodu bir anda taşımak zorunda değilsiniz. Tecrübeme göre önce kritik worker araçlarında denemek çok daha mantıklı. Yanı mevcut yapınız stabilse, kontrollü ve adım adım geçiş yapmak en sağlıklısı.
.NET 11’de detached process kullanmak güvenli mi?
Açık konuşayım, Evet, ama kontrollü kullandığınız sürece tabiî. Mesela detached süreçler iz bırakmadan çalışırsa operasyonel körlüğe yol açabiliyor. Açıkçası bu yüzden loglama ve izleme büyük ihtimalle yanında olmalı.
AOT kullanan uygulamalarda gerçekten fark yaratıyor mu?
Evet, özellikle trimmability tarafında faydası var (ciddiyim). Daha hafif API yüzeyi sayesinde binary boyutu ve gereksiz yük azalabiliyor. Ama kazancı görmek için publish profilinizi doğru kurmanız gerekiyor, yanı bu kısmı atlamamak lazım.
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.








Yorum gönder