İlkay İlknur

just a developer...

.NET Framework 4.0 - Paralel İterasyonların Break veya Stop Metotları ile Sonlandırılması

Merhaba Arkadaşlar,

Yaklaşık 1-1,5 haftadır bloguma herhangi birşey yazamadım. Bunun tek nedeni ise aslında tembellik.Smile Başka bir bahanenin arkasına sığınmıyorum.

Bu yazımızda ise yine paralel programlama konusundan devam ediyor olacağız ve Paralel olarak çalışan döngülerin nasıl sonlandırılabileceğini incelemeye çalışacağız. Bildiğimiz gibi paralel olmayan döngülerde Break metodunu kullanarak döngülerden çıkabiliyorduk. Ancak Paralel olarak çalışan döngülerde bu şekilde kullanım sözkonusu değil. Bunun nedeni ise aslında Paralel tarafta kullandığımız for döngüsünün aslında bir metot olması. Bu nedenle paralel döngüleri sonladırmak için ParallelLoopState tipi içerisinde bulunan Break ve Stop metotlarını kullanıyor olacağız. Bu iki metot arasında aslında anlatması ve anlaması biraz zor olan bir fark var. Bu farkı anlamak için isterseniz bir örnek yapalım ve daha detaylı bir şekilde inceleyelim.

İlk olarak ParallelLoopState tipine bakıyor olacağız. Parallel tipi içerisinde bulunan For ve Foreach metotlarına baktığımızda Action<int,ParallelLoopState> şeklinde iterasyon içerisinde işletilecek komutları alan aşırı yüklenmiş metotlar olduğunu görmekteyiz. Peki bu ParallelLoopState tipi ne işe yarıyor ? Bu tip aslında çalışma zamanı sırasında derleyici tarafından üretiliyor ve Paralel olarak işletilen döngü ile ilgili çeşitli işlemleri yapabilmemizi ve çeşitli durum bilgilerini almamızı sağlıyor. Bir de örneğimizde ConcurrentStack tipini kullanıyor olacağız. Bu tipte .Net Framework 4.0 ile beraber gelen Concurrent Collectionlar içerisinde yer almakta. Aslında bildiğimiz koleksiyonların paralel olarak çalışan versiyonları olarak özetleyebiliriz. Bu tipler ile ilgili detaylı olarak ilerleyen günlerde bir yazı yazıyor olacağım.

Örnek olarak ise elimizde 1 ile 1000 arasında integer değerleri tutan bir koleksiyon olacak ve paralel olarak bu koleksiyonu dolaşıp 500'den küçük değerleri elimizdeki ConcurrentStack içerisine ekleyeceğiz. Örnek kodumuz ise şu şekilde olacak.

static void Main()
{
   IEnumerable<int> sayilar = Enumerable.Range(1, 1000);
   ConcurrentStack<int> stack = new ConcurrentStack<int>();
   Parallel.For(0, sayilar.Count() - 1, (p, loopState) =>
           {
              Console.WriteLine("{0} sayısı kontrol ediliyor",p);
              if (p > 500)
                 loopState.Stop();
              else
                 stack.Push(p);
              if (loopState.IsStopped)
                 Console.WriteLine("{0} sayısını kontrol eden durduruldu", p);
           });
   Console.WriteLine("Stackte {0} eleman var",stack.Count);
}

Stop komutu yaratılmış olan ve yaratılacak tüm iterasyonlara mümkün olan en uygun  zamanda işlemlerini sonlandırma mesajı göndermektedir. Ayrıca ParallelLoopState tipi içerisindeki IsStopped propertysi ile de o anda çalışan iterasyona stop mesajı gönderilip gönderilmediğini de algılayabiliyoruz.

Örnek bir ekran görüntüsü ise şu şekilde

Yukarıda gördüğümüz gibi 998 sayısını kontrol ederken stop çağrısı gönderilmekte. Böylece yaratılan iterasyonlara işlemlerini en kısa sürede ve uygun zamanda bitirmeleri gerektiği çağrısı gönderilmiştir. Ancak yine de gördüğümüz gibi bazı iterasyonlar anında sonlanmamış çalışmalarına devam etmiştir. Böylece stacke 4 eleman eklenmiş durumda. Önemli olan bir nokta da diğer elemanları kontrol etmek için yaratılan paralel iterasyonların hiç işlem yapmadan sonlanmış olmaları.

Şimdi gelelim aynı örneği Break metodunu kullanarak yapmaya.

static void Main()
{
   IEnumerable<int> sayilar = Enumerable.Range(1, 1000);
   ConcurrentStack<int> stack = new ConcurrentStack<int>();
   Parallel.For(0, sayilar.Count() - 1, (p, loopState) =>
           {
              Console.WriteLine("{0} sayısı kontrol ediliyor",p);
              if (p > 500)
                 loopState.Break();
              else
                 stack.Push(p);
              if (loopState.IsStopped)
                 Console.WriteLine("{0} sayısını kontrol eden durduruldu", p);
           });
   Console.WriteLine("Stackte {0} eleman var",stack.Count);
}

Break metodu ise mesajın gönderildiği iterasyondan önce yaratılan iterasyonların işlemlerini bitirdikten sonra sonlanmaları mesajını vermektedir.

Burda da gördüğümüz gibi bu sefer stack içerisinde 501 eleman bulunmakta. Yani yaratılan iterasyonlar işlemlerine devam ettiler ve bu süreçte de gerekli kontroller yapılarak stack'e 501 eleman eklenmiş durumda.

Bir yazımızında daha sonuna geldik. Ancak yazıdan da anlayabileceğiniz üzere Break ve Stop metotları arasındaki fark biraz karmaşık. Bu nedenle farklı kaynaklardan da aynı konuda yazıları okumakta fayda var. Örneğin MSDN üzerinde aynı konu ile ilgili yazılmış olan yazıyı buradan inceleyebilirsiniz.

Görüşmek Üzere,



Yorum Gönder


Yorumlar

  • profile

    Tamer Güneş

    • 29
    • 4
    • 2013

    İlkay bey merhaba blogunuzu parallel programlamayla ilgili araştırma yaparken rastladım.Çok yardımcı oldu teşekkürler. Parallel programlamayla ilgili makalelerinizi bekliyorum iyi çalışmalar