Koray Kırdinli

Yazılım ve İş Yaşamı Hakkında Paylaşımlar

WPF Threading Modeli

Yazılım geliştirirken hep şu thread’ler başımın belası olmuştur. Öldürürsün ölmez,  açık kalır, debug ederken sıkıntı, memory şişer bulurken göbeğin çatlar, Pool’a at geri çağır sürekli hep sıkıntı yaratır. Bu dezavantajları olmasına rağmen onsuz da olmuyor ne yazık ki.  Neyseki Microsoft WPF ile birlikte thread kullanımını bana bırak sen business’a odaklan demeye başladı. Çünkü aslında hayal ettiğimiz birinci resimdeki gibi olmasına rağmen, gerçekleşen ne yazık ki ikinci resimdeki gibi olabiliyor :)

HAYALİMDEKİ MULTITHREADING                           ASLINDA OLAN MULTITHREADING
thread1               Thread2
WPF de temel olarak geri planda 2 thread bulunmakta; birisi rendering için diğeri UI’ı yönetmek için kullanılır.
Rendering thread UI’a veri getirirken, ekrana çizim yaparken, eventler’i handle ederken devreye girer.  UI Thread’i ise genellikle 1 tane olur, bazı durumlarda birden fazla da olabilir.

UI Thread’i çalışacak parçaları Dispatcher denen bir nesnede kuyruğa sokar ve öncelik sırasına göre çalıştırır. HEr bir UI threadi en az bir Dispatcher, ve herbir Dispatcher iş parçacıkları sadece 1 thread de çalıştırabilir. WPF de çoğu nesne DispatcherObject sınıfından türer.

Yazdığımız programın müşterileri memnun etmesi için tabi ki müşterinin her butona bastığında, her işlem yaptığında programın hızlıca cevap vermesi gerekiyor ve buradaki anahtar nokta da Dispatcher kuyruğuna atılacak iş parçacıklarının küçük olmasıdır, bu yöntem ile iş parçacıklarını kuyrukta fazla bekletmemiş oluruz.

Genel mantık olarak uzun sürecek işlemleri ana UI thread’inde değil ayrı bir thread de yapmamız gerekiyor. Eskiden windows uygulamaları yazarken bir UI nesnelerine sadece onu oluşturan thread üzerinden erişebilirken, WPF ile birlikte farklı thread’lerden de UI nesnelerini güncelleyebiliyoruz. Örneğin bir datagridi ana thread’den bağımsız olarak arka planda güncelleyebiliyor olmak büyük veriler ile çalışırken çok faydalı olacaktır. WPF bunu ana UI thread’inin dispatcherına iş parçacıkları register ederek sağlıyor. Dispatcher.Invoke, Dispatcher.BeginInvoke metodları bu register işlemini yapar. Invoke senkron, BeginInvoke asenkron çalışır. Bunların önceliklerini de DispatcherPriority enumu ile belirtebilirsiniz.

Örnek kullanım : Yeni bir thread açarak dispatcher invoke yöntemiyle UI daki listbox ekran kilitlenmeden doldurulabiliyor.

Thread tt = new Thread(FillListBox);
tt.Start();

private void FillListBox()
{
for (int i = 0; i < 500; i++)
{
listBox1.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
listBox1.Items.Add(“A” + i.ToString());
});

Thread.Sleep(100);

}
}

May 28, 2015 - Posted by | C#, WPF | , , , ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s