Değerli Okurlarım, Merhabalar.
İş parçacıklarını işlediğimiz yazı dizimizin bu üçüncü makalesinde, iş parçacıklarının birbirlerine karşı öncelik durumlarını incelemeye çalışacağız. İş parçacıkları olarak tanımladığımız metodların çalışma şıralarını, sahip oldukları öneme göre değiştirmek durumunda kalabiliriz. Normal şartlar altında, oluşturduğumuz her bir iş parçacığı nesnesi aynı ve eşit önceliğe sahiptir. Bu öncelik değeri Normal olarak tanımlanmıştır. Bir iş parçacığının önceliğini değiştirmek istediğimizde, Priority özelliğinin değerini değiştiririz. Priority özelliğinin .NET Framework'teki tanımı aşağıdaki gibidir.
public ThreadPriority Priority {get; set;}
Özelliğimiz ThreadPriority numaralandırıcısı (enumerator) tipinden değerler almaktadır. Bu değerler aşağıdaki tabloda verilmiştir.
Öncelik Değeri |
Highest |
AboveNormal |
Normal |
BelowNormal |
Lowest |
Tablo 1. Öncelik(Priority) Değerleri
Programlarımızı yazarken, iş parçacıklarının çalışma şekli verilen öncelik değerlerine göre değişecektir. Elbette tahmin edeceğiniz gibi yüksek öncelik değerlerine sahip olan iş parçacıklarının işaret ettikleri metodlar diğerlerine göre daha sık aralıklarda çağırılacak, dolayısıyla düşük öncelikli iş parçacıklarının referans ettiği metodlar daha geç sonlanacaktır. Şimdi olayı daha iyi canlandırabilmek için aşağıdaki örneğimizi geliştirelim. Daha önceden söylediğimiz gibi, bir iş parçacığının Priority özelliğine her hangibir değer vermez isek, standart olarak Normal kabul edilir. Buda tüm iş parçacıklarının varsayılan olarak eşit önceliklere sahip olacakları anlamına gelmektedir. Şimdi aşağıdaki formumuzu oluşturalım. Uygulamamız iki iş parçacığına sahip. Bu parçacıkların işaret ettiği metodlardan birisi 1' den 1000' e kadar sayıp bu değerleri bir label kontrolüne yazıyor. Diğeri ise 1000' den 1' e kadar sayıp bu değerleri başka bir label kontrolüne yazıyor. Formumuzun görüntüsü aşağıdakine benzer olmalıdır.

Şekil 1. Form Tasarımımız.
Şimdide program kodlarımızı yazalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | public void Say1()
{
for ( int i=1;i<1000;++i)
{
lblSayac1.Text=i.ToString();
lblSayac1.Refresh();
for ( int j=1;j<90000000;++j)
{
j+=1;
}
}
}
public void Say2()
{
for ( int i=1000;i>=1;i--)
{
lblSayac2.Text=i.ToString();
lblSayac2.Refresh();
for ( int j=1;j<45000000;++j)
{
j+=1;
}
}
}
ThreadStart ts1;
ThreadStart ts2;
Thread t1;
Thread t2;
private void btnBaslat1_Click( object sender, System.EventArgs e)
{
ts1= new ThreadStart(Say1);
ts2= new ThreadStart(Say2);
t1= new Thread(ts1);
t2= new Thread(ts2);
t1.Start();
t2.Start();
btnBaslat1.Enabled= false ;
btnIptal.Enabled= true ;
}
private void btnIptal_Click( object sender, System.EventArgs e)
{
t1.Abort();
t2.Abort();
btnBaslat1.Enabled= true ;
btnIptal.Enabled= false ;
}
private void btnKapat_Click( object sender, System.EventArgs e)
{
if ((!t1.IsAlive) && (!t2.IsAlive))
{
Close();
}
else
{
MessageBox.Show( "Hala kapatılamamış iş parçacıkları var. Lütfen bir süre sonra tekrar deneyin." );
}
}
|
Uygulamamızda şu an için bir yenilik yok aslında. Nitekim iş parçacıklarımız için bir öncelik ayarlaması yapmadık. Çünkü size göstermek istediğim bir husus var. Bir iş parçacığı için herhangibir öncelik ayarı yapmadığımızda bu değer varsayılan olarak Normal dir. Dolayısıyla her iş parçacığı eşit önceliğe sahiptir. Şimdi örneğimizi çalıştıralım ve kafamıza göre bir yerde iptal edelim.

Şekil 2. Öncelik değeri Normal.
Ben 11 ye 984 değerinde işlemi iptal ettim. Tekrar iş parçacıklarını Başlat başlıklı butona tıklayıp çalıştırırsak ve yine aynı yerde işlemi iptal edersek, ya aynı sonucu alırız yada yakın değerleri elde ederiz. Nitekim programımızı çalıştırdığımızda arka planda çalışan işletim sistemine ait pek çok iş parçacığıda çalışma sonucunu etkiler. Ancak aşağı yukarı aynı veya yakın değerle ulaşırız. Oysa bu iş parçacıklarının öncelik değelerini değiştirdiğimizde sonuçların çok daha farklı olabilieceğini söyleyebiliriz. Bunu daha iyi anlayabilmek için örneğimizi geliştirelim ve iş parçacıklarının öncelik değerleri ile oynayalım. Formumuzu aşağıdaki gibi tasarlayalım.

Şekil 3. Formumuzun yeni tasarımı.
Artık iş parçacıklarını başlatmadan önce önceliklerini belirleyeceğiz ve sonuçlarını incelemeye çalışacağız. Kodlarımızı şu şekilde değiştirelim. Önemli olan kod satırlarımız, iş parçacıklarının Priority özelliklerinin değiştiği satırlardır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | public void Say1()
{
for ( int i=1;i<1000;++i)
{
lblSayac1.Text=i.ToString();
lblSayac1.Refresh();
for ( int j=1;j<90000000;++j)
{
j+=1;
}
}
}
public void Say2()
{
for ( int i=1000;i>=1;i--)
{
lblSayac2.Text=i.ToString();
lblSayac2.Refresh();
for ( int j=1;j<45000000;++j)
{
j+=1;
}
}
}
ThreadPriority tp1;
ThreadPriority tp2;
public void OncelikBelirle()
{
switch (tbOncelik1.Value)
{
case 1:
{
tp1=ThreadPriority.Lowest;
break ;
}
case 2:
{
tp1=ThreadPriority.BelowNormal;
break ;
}
case 3:
{
tp1=ThreadPriority.Normal;
break ;
}
case 4:
{
tp1=ThreadPriority.AboveNormal;
break ;
}
case 5:
{
tp1=ThreadPriority.Highest;
break ;
}
}
switch (tbOncelik2.Value)
{
case 1:
{
tp2=ThreadPriority.Lowest;
break ;
}
case 2:
{
tp2=ThreadPriority.BelowNormal;
break ;
}
case 3:
{
tp2=ThreadPriority.Normal;
break ;
}
case 4:
{
tp2=ThreadPriority.AboveNormal;
break ;
}
case 5:
{
tp2=ThreadPriority.Highest;
break ;
}
}
t1.Priority=tp1;
t2.Priority=tp2;
}
ThreadStart ts1;
ThreadStart ts2;
Thread t1;
Thread t2;
private void btnBaslat1_Click( object sender, System.EventArgs e)
{
ts1= new ThreadStart(Say1);
ts2= new ThreadStart(Say2);
t1= new Thread(ts1);
t2= new Thread(ts2);
OncelikBelirle();
t1.Start();
t2.Start();
btnBaslat1.Enabled= false ;
btnIptal.Enabled= true ;
tbOncelik1.Enabled= false ;
tbOncelik2.Enabled= false ;
}
private void btnIptal_Click( object sender, System.EventArgs e)
{
t1.Abort();
t2.Abort();
btnBaslat1.Enabled= true ;
btnIptal.Enabled= false ;
tbOncelik1.Enabled= true ;
tbOncelik2.Enabled= true ;
}
private void btnKapat_Click( object sender, System.EventArgs e)
{
if ((!t1.IsAlive) && (!t2.IsAlive))
{
Close();
} else
{
MessageBox.Show( "Hala kapatılamamış iş parçacıkları var. Lütfen bir süre sonra tekrar deneyin." );
}
}
|
Şimdi örneğimizi çalıştıralım ve birinci iş parçacığımız için en yüksek öncelik değerini (Highest) ikinci iş parçacığımız içinde en düşük öncelik değerini (Lowest) seçelim. Sonuçlar aşağıdakine benzer olucaktır.

Şekil 4. Önceliklerin etkisi.
Görüldüğü gibi öncelikler iş parçacıklarının çalışmasını oldukça etkilemektedir. Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde iş parçacıkları hakkında ilerlemeye devam edeceğiz. Görüşmek dileğiyle hepinize mutlu günler dilerim.