Hata Yönetiminin İş Mantığı Olarak Kullanımı

It's okay! I wrote an exception!   Yazgeliştir Asp.Net web forumlarında Request.QueryString’in null gelmesi ile başlayan bir hata hakkında gelen soru farkında olmadan beraberince çok güzel bir konuyu açtı; hata yakalamanı/fırlatmanın iş mantığı olarak kullanımı. Gelen ilk öneri aslında teorik olarak kötü bir öneri değildi; query string okuması yapılan bölümün try-catch bloğuna alınarak boş değer gelmesi durumunda hatanın uygulamayı etkilemesinin önüne geçilmesi öneriliyordu:

 

 

 

Dim gelen as integer

try
   gelen = request.querystring("gelen")
catch

end

   Bu yanıtın hemen ardından gelen ikinci bir yanıt daha vardı; null kontrolü;

if(Request.QueryString["myvalue"] != null){
   //do whatever you want here
}

   Teorik olarak bakıldığında her iki yanıtta problemi ortadan kaldırıyordu ve soruda geçen iş mantığında da herhangi bir probleme sebep olmuyordu. Peki pratikte durum nasıl? İkisi arasında pratikte bir fark var mı? varsa hangisi neden tercih edilmeli?

   Öncelikle belirtmeliyim ki, ilk cevaptaki gibi bir kullanımı kesinlikle önermiyorum. Burada bir iş mantığı çalışmakta, ve iş mantığının try-catch’lerle ya da hata fırlatılarak yönetilmesi kesinlikle önermediğim bir yöntem. Hatta mümkünse gerçekten gerekmediği sürece kodunuzda hata fırlatmamanızı özellikle tavsiye ediyorum.

   Hata yönetimi yazılım dünyasında, programlama dilinden bağımsız olarak, her zaman maliyetli bir yöntem olmuştur. Bu maliyet C# gibi managed dillerde ise daha da fazla olabilmekte.

   Managed dünyada hata fırlatma/yakalamadı iki grup maliyetten söz edebiliriz. İlk maliyet görece daha önemsiz olan statik maliyettir ve hata yakalama/fırlatma için uygulama içerisine eklenen ek kodu kapsamaktadır. Yukarıdaki örnekten yola çıkacak olursak; bir if ile yapılabilecek basit bir kontrol yerine Intermediate language (IL) kodu içerisine hata yakalama için pek çok ekleme yapılacaktır. Başta da belirttiğim gibi her ne kadar derleyici tarafından eklenen kodlarla ek işlemci zamanını kullanıyor olsa da static maliyet görece katlanılabilir bir maliyettir ve özellikle unmanaged dillerle kıyaslayacak olursak daha düşüktür; çünkü managed diller hata yönetimi desteğiyle birlikte gelmektedirler.

   Öte yandan ikinci ve asıl önemli maliyet çalışma zamanında karşımıza çıkacaktır. Kod içerisinde bir hata oluşması durumunda hata bilgilerinin tutulacağı nesne(ler) oluşturularak hafızada tutulacak, siz kullansanız da, (yukarıda olduğu gibi) kullanmasanız da tüm çağırma hiyerarşisi (full call stack) bilgisi toplanacaktır. Özellikle çağırma hiyerarşisinin oluşturulması azımsanmayacak bir işlemci zamanı ve hafıza alanı alabilir. Paralelde Windows sizin için standart hata yakalama prosedürlerini işletecek (Structured Exception Handling ya da Vectored Exception Handling) ve uygulamanın tüm çalışması durdurularak mevcut işlemci registery ve pointerları bir yerde depolanarak hata yakalama prosedürünüz işletilmeye başlanacaktır. Üstelik bu işlem iki defa yapılacaktır. Structured Exception Handling (SEH) ya da Vectored Exception Handling (VEH) yöntemleri hakkında daha önceden sizlerle paylaşmış olduğum makalemde daha detaylı bilgi bulabilirsiniz.

     İsterseniz hata fırlatma/yakalama maliyetini örnek bir uygulama üzerinden inceleyelim. Örnek bir asp.net sayfasının kodlarını bulabileceğiniz aşağıdaki bölümde Deneme türündeki denemeNesnesi’nin boş gelme ihtimaline karşılık null kontrolü yapılması yerine try-catch ile mantık kurulmasının maliyetini karşılaştırabilirsiniz;

public partial class _Default : System.Web.UI.Page {
    public class Deneme {
        public int X;
    }

    protected void Page_Load(object sender, EventArgs e) {
        var saat = new System.Diagnostics.Stopwatch();
        int xDegeri;
        Deneme denemeNesnesi = null;


        saat.Start();
        for (int i = 0; i < 20000; i++) {
            try {
                xDegeri = denemeNesnesi.X;
                //...
            }
            catch { }
        }
        saat.Stop();

        Response.Write("<p>hata fırlatma ile süre : " + saat.ElapsedMilliseconds + " ms</p>");

        saat.Reset();
        saat.Start();
        for (int i = 0; i  < 20000; i++) {
            if (denemeNesnesi != null) {
                xDegeri = denemeNesnesi.X;
            }
        }
        saat.Stop();

        Response.Write("<p>if ile süre : " + saat.ElapsedMilliseconds + " ms</p>");
    }
}

   Kod içerisindeki iki farklı kullanımın maliyetini daha iyi görebilmek adına her iki işlemde 20000 kez tekrarlanmakta ve işlemin süresi bir Stopwatch ile ölçülmekte.

   Bu kodu çalıştırdığınızda aşağıdaki çıktıyı alacaksınız (süreler donanıma göre değişkenlik gösterebilir);

hata fırlatma ile süre : 84567 ms

if ile süre : 0 ms

  Görüldüğü gibi iki yaklaşım arasında önemli bir zaman farkı bulunmakta. Bir de iş mantığınız içerisinde hataları yakalaya yakalaya ilerlediğinizi düşündüğümüzde ortaya çıkan uygulama son kullanıcı açısından tam bir kabusa dönüşebilme potansiyeline sahiptir. İşte tam da bu yüzden, gerçekten gerekmediği sürece hata yakalama/fırlatma mekanizmasını iş mantığı için kullanmayın. Kodunuz içerisinde tahmin edebildiğiniz ve kontrol edebildiğiniz tüm hataları kontrol etmeniz, iş mantıklarınızı fonksiyondan hata fırlatarak değil değer dönerek geliştirmeniz önemli.

Fatih Boy

Ankara'da yaşayan Fatih, bir kamu kurumunda danışman olarak çalışmaktadır. ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook - Google+

1 Yorum

  1. tugberk   •  

    harika bir yazı. .Net ile uygulama yaratmak basit fakat *Uygulama* yaratmak gerçek bir bilgi ve tecrübe gerektiriyor. Bununda burada en iyi şekilde anlıyoruz.

Bir Cevap Yazın

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