İlkay İlknur

Just a developer

.NET Framework 4.0 – Parallel.For ve Parallel.Foreach ile Döngülerin Paralel Olarak İşletilmesi

Merhaba ArkadaÅŸlar,

.NET Framework 4.0 ile beraber gelecek olan paralel programlama altyapısına göz atacağımız ilk yazımızda basit olarak for ve foreach döngülerini nasıl paralel bir şekilde çalıştırabiliriz bunu inceliyor olacağız. Paralel olarak for ve foreach döngülerini çalıştırmak için TPL(Task Parallel Library) içerisinde bulunan metotları kullanıyor olacağız. TPL içerisinde bulunan For ve Foreach metotları sayesinde düngülerin paralel bir şekilde işletilmesi için gereken tüm işlemler TPL tarafından otomatik olarak ele alınmaktadır. Bizim yapmamız gereken ise sadece ilgili değerleri vermek. Öncelikle for ve foreach döngülerini nasıl paralel bir şekilde çalıştırabiliriz bunu incelemeye çalışalım. Paralel döngüler için Parallel tipi içerisinde bulunan For ve Foreach metotlarını kullanıyoruz. For metodunun parametrelerine bakarsak.

Parallel.For(int fromInclusive, int toExclusive, Action<int> body)

  • fromInclusive : For döngüsünün baÅŸlayacağı deÄŸer.
  • toExclusive : For döngüsünün döneceÄŸi son deÄŸer.
  • body : For döngüsünün içerisinde yapılacak iÅŸlemler.
Body parametresinin tipi Action<int> olarak görülmektedir. Yani biz bu parametre için C# 3.0 ile beraber gelen lambda ifadelerini kullanabiliriz.Wink Temel kullanım ise şu şekilde:
 //0′dan 9′a kadar dönen for döngüsü
Parallel.For(0,10,p=>
{
   //İşlemler
});

Foreach metoduna baktığımızda ise yine for döngüsüne benzer bir imza ile karşılaşıyoruz.

Parallel.Foreach(IEnumerable<TSource> source, Action<TSource> body)

  • source : Foreach iÅŸlemi boyunca içerisinde dolaÅŸacağımız IEnumerable arayüzünü implemente etmiÅŸ olan koleksiyon
  • body : Foreach döngüsü içerisinde ele alacağımız iÅŸlemler.
Foreach döngüsünün de temel kullanımı şu şekilde:
IEnumerable<int> numbers = Enumerable.Range(1,1000);
Parallel.ForEach(numbers, p =>
    {
        //numbers hangi tipi taşıyan koleksiyon ise 
       //p parametresi de o tipte
      //işlemler
    });

Basit olarak for ve foreach döngülerinin nasıl parallelize edildiğini görmüş olduk. Şimdi ise bir örnek üzerinde for ve foreach döngülerini kullanalım ve biraz daha derine inerek ne gibi işlemler gerçekleşiyor ve döngüler nasıl işletiliyor incelemeye çalışalım. Aşağıdaki gibi bir Çalışan sınıfımız olduğunu düşünelim ve çalışanların toplam alacağı ücretleri paralel bir şekilde hesaplayalım ve daha sonra ekrana yazdıralım.

public class Calisan
{
    public int ID { get; set; }
    public double SaatlikUcret { get; set; }
    public double ToplamCalisma { get; set; }
}

Elimizde çeÅŸitli deÄŸerler ile yaratılmış olan bir Calisan listesi olduÄŸunu düşünelim ve paralel foreach döngüsü ile gerekli hesaplamayı yaparak Console’a sonuçları yazdıralım.

static void Hesapla(List<Calisan> calisanlar)
{
    Parallel.ForEach(calisanlar, calisan =>
            {
               double total = calisan.SaatlikUcret * calisan.ToplamCalisma;
               Console.WriteLine(“{0} numaralı çalışanın alacağı toplam ücret:{1}\n”,calisan.ID,total);
            });
}

Son olarak listeyi yaratacağımız ve çeşitli çalışan nesneleri ile doldurup Hesapla metodunu çağıracağımız Main metot ise şu şekilde.

static void Main(string[] args)
{
    List<Calisan> calisanlar = new List<Calisan>()
    {
        new Calisan(){ID=1,SaatlikUcret=10,ToplamCalisma=30},
        new Calisan(){ID=2,SaatlikUcret=12,ToplamCalisma=34},
        new Calisan(){ID=3,SaatlikUcret=8,ToplamCalisma=38},
        new Calisan(){ID=4,SaatlikUcret=14,ToplamCalisma=39},
        new Calisan(){ID=5,SaatlikUcret=18,ToplamCalisma=37},
    };
    Hesapla(calisanlar);
}

Uygulamayı çalıştırıp sonuçlara bakarsak.

Gördüğümüz gibi listeye çalışan nesnelerini ID’leri sıralı olacak ÅŸekilde eklememize raÄŸmen foreach döngüsü içerisinde farklı sıralarda iÅŸletildiÄŸini görmekteyiz. Uygulamayı her çalıştırdığımızda ise sürekli olarak farklı sonuçlarla karşılaÅŸmamız oldukça normaldir. Bunun nedeni ise foreach döngüsü içerisinde paralel iÅŸlemek için yaratılan threadlerin iÅŸlemci tarafından farklı sıralarda iÅŸleme alınmasıdır. Bunu görmek için Hesapla metodunu aÅŸağıdaki gibi deÄŸiÅŸtirip uygulamayı yeniden çalıştırırsak daha kolay bir ÅŸekilde threadleri takip edebiliriz.

static void Hesapla(List<Calisan> calisanlar)
{
    Parallel.ForEach(calisanlar, calisan =>
            {
                 int threadid = Thread.CurrentThread.ManagedThreadId;
                 double total = calisan.SaatlikUcret * calisan.ToplamCalisma;
                 Console.WriteLine(“İşlem {0} nolu thread tarafından gerçekleÅŸtirildi.\n
                 {1} numaralı çalışanın alacağı toplam ücret:{2}\n”,threadid,calisan.ID,total);
            });
}

Çıkan sonuçlara baktığımızda hemen hemen herbir çalışanın toplam alacağı ücret farklı bir thread üzerinden hesaplandığını görmekteyiz. Tabi her çalıştırdığımızda farklı bir sonuç görmemiz normal bir durumdur. Bazen tek bir thread id’ye sahip olan bir thread üzerinden de iÅŸlemler yapılabilir.

Yazımızın sonuna gelirken kısaca bir özetlersek basit olarak for ve foreach döngülerini Task Parallel Library kullanarak nasıl parallelleştirebiliriz bu konu üzerinde durduk ve birkaç basit örnek yaptık. İlerleyen yazılarda da daha kompleks senaryolar üzerinde duracağız ve döngülerin paralelleştirilmesini daha da detaylı bir şekilde inceleyeceğiz.

Åžimdilik bu kadar,

Görüşmek Üzere,

No Responses to “.NET Framework 4.0 – Parallel.For ve Parallel.Foreach ile Döngülerin Paralel Olarak İşletilmesi”

RSS feed for comments on this post. TrackBack URL

Leave a Response