Masaüstü ya da Mobil Cihaz Form uygulamalarında yaşanan en
büyük problemlerden birisi döngülerin çalıştırıldığı süreç esnasında uygulama
ekranı üzerinde yaşanan kilitlenmelerdir. Bu konuyla ilgili daha önce
http://www.yazgelistir.com/Makaleler/1000001208.ygpx
adresinde Asenkron Mimarinin uygulanması ; başka bir deyişle işlemlerin farklı
bir thread içerisinden yürütülerek halledilebileceğinden bahsetmiştik. Bu
makalemizde ise işlemlerin çalıştırılma süreci içerisinde yaşanan bu
beklemelerin temel sebebinden bahsedip ; buna farklı bir perspektiften ;
Application.DoEvents() metodu üzerinden çözüm arayacağız.
Asıl konumuza geçmeden önce işletim sistemimiz üzerinde bir
uygulama başladığı andan itibaren yaşanan süreçten bahsedelim. Bilindiği üzere
Windows CE ya da herhangi bir Windows tabanlı işletim sistemi üzerinde herhangi
bir kaynak üzerinde gerçekleşen bir olay ile ilgili işletim sisteminin
gösterdiği tepkilere bildiğimiz “Olay (Event)” ismi yerine “Mesaj (Message)”
ismi verilmektedir. Bu noktada işletim sistemi üzerinde gerçekleştirilen
herhangi bir eylem uygulama geliştiriciye Mesaj olarak gönderilmektedir. Zaten
Buton üzerinde tıkladığımızda ilgili buton’ un tıklatıldığını işletim
sistemimiz donanımsal seviyeden yakalayıp .Net Framework’ e iletmekte ; Olay
(Event) olarak tanımladığımız tetikleyiciler uygulamalarımızda
fırlatılmaktadır.
Üzerinde konuştuğumuz bu süreç ana uygulama herhangi bir
sebepten kapatılmadığı ya da sonlandırılmadığı süre boyunca istisnasız devam
etmekte ; gerçekleştirdiğimiz her eylemin karşılığında işletim sistemimiz
üzerinden mesajlar fırlatılmakta ve bu mesajlar .Net Framework tarafından
yakalanıp işletilmektedir.
Konuyu biraz daha ayrıntılı incelediğimizde istisnasız devam
eden bu süreç içerisinde incelenmesi gereken –ki sorunun temel kaynağı olarak
ifade edilebilecek- önemli bir başlık daha bulunmaktadır.
Bir önceki örneğimizde uygulama ekranımız üzerine
yerleştirilen standart bir button’ un üzerinde gerçekleştirilebilecek en
standart eylemden ; üzerine tıklamaktan bahsettik. Bu noktada mantık
çerçevesinde düşünüldüğünde ekran üzerinde aynı anda iki butona
tıklayamayacığımız açık ve net bir sonuçtur.
Olaya bu açıdan baktığımızda standart yaklaşımla
gerçekleştirdiğimiz eylemlere karşılık olarak gönderilen mesajlar işletim
sistemimiz üzerinde belirli bir sırayla gönderilip işletilmektedir. Özel,
spesifik bir durum dışında bir eylem sonucunda belirli bir iş
gerçekleştirildiğinde işletim sistemi üzerinden gönderilen diğer mesajlar
uygulama tarafında bekletilmekte ; bir önceki mesajın sonucu başlatılan iş
tamamlanana kadar işletilmemektedirler. Peki bu noktada yaşanan nasıl bir
problem olabilir ; biraz bu konuya değinelim.
Örnek bir senaryo olarak makalemizin başında adresi verilen
Asenkron Mimari ile ilgili makalemizde gerçekleştirilen bir senaryoyu ele
alalım. Uygulama içerisinde belirli iki sayı arasında ; ya da belirli bir koşul
gerçeklendiği zaman sürecinde onlarca belki yüzlerce kez çalışması gereken bir
döngünün olduğunu düşünelim. Bu döngünün döndürüldüğü ; başka bir deyişle
çalıştırıldığı süreç içerisinde ise görsel anlamda bazı görevleri yerine
getirelim-ki örnek vermek gerekirse gelen her sayıyı bir liste kutusu içerisine
eklemek olabilir.
Bir önceki paragrafta anlatıldığı üzere bu “iş”
gerçeklenirken işletim sistemi üzerinden onlarca ; belki yüzlerce mesaj
fırlatılmakta, fakat o süreç boyunca sistem “döngü” ‘ ye odaklandığı ve onunla
ilgili mesajları işlediği için diğer mesajları kuyrukta bekletmektedirler.
Peki az önce üzerinde konuştuğumuz üzere ; özel &
spesifik bir durumdan bahsediyorsak ; yani döngü dönerken liste kutusu
içerisine eklenen rakamları canlı olarak görmek istiyorsak ; daha açık anlatmak
gerekirse gelen rakamların liste kutusuna eklenmesi ile ilgili işletim sistemi
üzerinden gelen mesajların döngü çalışırken işletilmesi için nasıl bir yapıyı
uygulamamız gerekmektedir ?
İşte bu noktada makalemizin başlığını oluşturan bir metot ;
Application sınıfı içerisinde bulunan DoEvents() metodu karşımıza çıkmaktadır.
Application.Run() metodu ile yaşam sürecine başlayan Windows
Form uygulamamız içerisinde kuyrukta bekletilen mesajların işlenmesi ile ilgili
bir metot olan DoEvents() metodu makalemizinde konusunda ifade edildiği üzere
bu tip bekletme durumlarında hayat kurtarmaktadır. Özellikle döngü, koşul bazlı
süreçler ele alındığında kullanıcılar kuyrukta bekletilen mesajları işleterek
sistemin “olması gerektiği gibi” çalışmasını sağlayabilmektedirler.
Bu noktada konunun daha rahat anlaşılabilmesi açısından
örnek bir uygulama geliştirmek çok doğru olacaktır. Senaryomuza göre bir while
döngüsü içerisinde koşul sağlandığı sürece o an aktif sayaç değeri liste
kutusuna eklenecek ; bu ekleme işinin görsel sonucu canlı olarak ekranda
gösterilecektir.
Bunun için ilk olarak bir Smart Device C# uygulaması
açıyoruz.

Bir sonraki adımda form üzerine bir buton ve bir liste
kutusu kontrolü yerleştiriyoruz.

Ve şekildeki kodları yazarak uygulamamıza devam ediyoruz :

Kodu incelediğimizde basit bir while döngüsünün
hazırlandığını rahatlıkla farkedebiliriz. Gerçekleştirdiğimiz tek eylem ise
Button’ a tıkladığımızda koşulun sağlanıp sağlanmadığını kontrol etmek ; koşul
sağlandığı süre içerisinde de Sayac değerini liste kutusu içerisine eklemek
olacaktır. Bu şekilde uygulamamızı çalıştırdığımızda ise :

Scrollbar’ ın küçüldüğünü ; yani sayıların eklenmesi ile
ilgili mesajların geldiğini fakat bunların görsel anlamda işletilemediğini
rahatlıkla görebiliriz. Bu noktada yaşanan problem ile ilgili yazının başında
ayrıntılı bir açıklamada bulunmuştuk. Yapmamız gereken tek şey bekletilen
mesajların kuyruktan çekilmesi ve işletilmesi olacaktır ; ki bu noktada
Application.DoEvents() metodu karşımıza çıkmaktadır.
Application.DoEvents() metodu her çağırıldığında kuyrukta
bekletilen mesajlar otomatik olarak işlem görmektedir. Bu noktada döngü her
döndüğünde bu mesaj sayısı yükselmekte ; haliyle kimi zaman tıkanmalara sebep
olabilmektedir. Bizim bu noktada yapabileceğimiz tek şey döngü her döndüğünde
Application.DoEvents() metodunu çağırmak ve anlık olarak sırada bekletilen
mesajı ; yani sayının liste kutusuna eklenmesi ile ilgili işlemi
gerçekleştirmemiz olacaktır. Kodu şekildeki gibi tekrar düzenleyip
çalıştırıyoruz :

Uygulamayı çalıştırdığımızda ise :

Ve sonuç mükemmel ! İşlem devam ediyor olmasına karşın
sayılar ekran üzerinde başarıyla görüntülenmektedir.
Bu makalemizde Application.DoEvents() metodu ile kuyrukta
bekletilen işletim sistemi mesajlarını kuyruktan çekmeyi mercek altına aldık.
Başka bir makalede daha görüşmek üzere.