Makale Özeti

Threadlerin yaratılması, çalıştırılması

Makale

C# ile Thread Kullanımına Giriş


Programımızın aynı anda birden fazla görevi yapmasını istediğimizde Thread kullanmamız gerekir. Örneğin, programımız arkada yoğun hesaplarla meşgulken kullanıcı arayüzüne de değerler basmasını istiyorsak, veya yüzbinlerce e-postayı posta sunucusunu daha fazla meşgul ederek hızlı bir şekilde göndermek istiyorsak thread kullanmalıyız.

Threadlerin çalışma mantığıyla ilgili bilgi edinmek için Aykut Taşdelenin Visual Basic.NET İle MultiThread Programlama makalesini okuyabilirsiniz. Ben bu makalede C# kullanarak threadlerin yaratılması ve kullanılmasını açıklamaya çalışacağım.
 
Threadlerin yaratılması:
 
Yeni bir thread yaratmak için Thread sınıfından bir nesne türetmemiz gerekiyor. Bunun için de thread sınıfının yaratıcısına, thread başladığında çalıştırılacak metodu gösteren bir delege geçmemiz gerekiyor.
 

     Thread threadim = new Thread (new ThreadStart(CalistirilacakMetodum));
 


Threadımızı yarattıktan sonra, threadımızın start metodunu kullanarak, threadımızı  çalışmaya başlatıyoruz.
 

threadim.Start();


Şimdi iki tane thread yaratarak çalıştıran bir programa ve çıktısına gözatalım. 0’dan 99a kadar sayan iki tane metodumuz olsun, ve programımız bu iki threadı çalıştırsın.
 

using System;
using System.IO;
using
System.Threading;

namespace Threadler{

      class Sinifim

      {

            static void Main(string[] args)

            {

                  Sinifim s = new Sinifim();

                  s.ThreadleriCalistir();            

            }

            public void ThreadleriCalistir(){

                  Thread thread1 = new Thread(new ThreadStart(Say1));

                  Thread thread2 = new Thread(new ThreadStart(Say2));

                  thread1.Start();

                  thread2.Start();

                  Console.WriteLine("Threadleri calistirdim, isim bitti...");
                  Console.WriteLine("Güle Güle");

            }

            public void Say1(){

                  for(int i =0;i<100;i++){

                        Console.WriteLine("Say1:"+i.ToString());

                  }

            }

            public void Say2()
            {

                  for(int i =0;i<100;i++)

                  {

                        Console.WriteLine("Say2:"+i.ToString());

                  }

            }

      }

}

Programı çalıştırdığımda benim bilgisayarımda şöyle bir çıktı veriyor:

Threadleri çalıştırdım, işim bitti...
Gule Gule

Say1:0
Say1:1
Say1:2
Say1:3
Say1:4
Say1:5
Say1:6
Say1:7
Say1:8
Say1:9
Say1:10
Say1:11
Say1:12
Say1:13
Say1:14
Say1:15
Say1:16
Say1:17
Say2:0
Say2:1
Say2:2
Say2:3
Say2:4
Say2:5
Say2:6
Say2:7
Say2:8
Say2:9
...

Program önce Say1 metodunu bir süre çalıştırmış, sonra ise Thread2 ye süre vererek Say2 metodunu çalıştırmış. Iki metodum da paralel bir şekilde çalışıyor.

Güzel, fakat threadlerimizi çalıştıran ThreadÇalıstır metodu, threadlerin çalışmasını bitirmeden “güle güle” dedi. Threadlerimizin işi bitmeden kendi işini bitirdi ve çıktı.

 

Threadleri birleştirmek:


Az önceki durumun önüne geçmek için, aslında genel olarak , bir threadin baska bir thread bitmeden çalışmamasını istiyorsak threadleri birleştirmeliyiz. Bunun icin Thread sınıfının Join metodunu kullanmalıyız.

Programımın herhangi bir noktasında

birlesilecekThread.Join() ;


diyerek, o noktada o anki threadin çalışmasının durarak, birleştirilecek threadin çalışması bittikten sonra çalışmaya devam etmesini sağlayabiliyorum.

Şimdi az önceki kodumuza bunu ekleyelim ve sonucu görelim:

 

using System;
using
System.IO;
using
System.Threading;

namespace Threadler

{

      class Sinifim

      {

            static void Main(string[] args)

            {

                  Sinifim s = new Sinifim();

                  s.ThreadleriCalistir();            

            }

            public void ThreadleriCalistir(){

                  Thread thread1 = new Thread(new ThreadStart(Say1));

                  Thread thread2 = new Thread(new ThreadStart(Say2));

                  thread1.Start();

                  thread2.Start();

                  Console.WriteLine("Threadleri calistirdim, isim bitti...");

                 

                  // iki thread de calissin, ondan sonra gule gule diyeyim

                  thread1.Join();

                  thread2.Join();

                  Console.WriteLine("Güle Güle");

           

            }

            public void Say1(){

                  for(int i =0;i<100;i++){

                        Console.WriteLine("Say1:"+i.ToString());

                  }

            }

            public void Say2()

            {

                  for(int i =0;i<100;i++)

                  {

                        Console.WriteLine("Say2:"+i.ToString());

                  }

            }

      }

}


Bu programın çıktısı ise şu şekilde:

 Threadleri çalıştırdım, işim bitti...

Say2:0

Say2:1

Say2:2

Say2:3

Say2:4

Say1:0

Say1:1

Say1:2

...

Say2:96

Say2:97

Say2:98

Say2:99

Güle Güle

 

 

Programı çalıştıran thread, diğer iki threadle birleşti, ve onların çalışmasının bitmesini bekledi. Sonra da işlemini tamamlayarak çıktı.

Bu makalede C# diliyle threadlerin kullanımına giriş yapmış olduk. Threadler gerek kullanıcıya daha hızlı arayüz tepkileri verilmesinde, gerekse, e-posta gönderme, Internetten bilgi okuma gibi I/O bekleyen durumlarda programımızın başka işler yaparak hızlanmasına yardımcı olan yapılardır. Fakat gereksiz kullanımındaysa bir threadden diğerine geçerken oluşan thread değiştirme zamanı nedeniyle performans kaybına yolaçabildiği gibi, kodu da daha karmaşık hale getirerek programımızın kontrolünü zorlaştıracaktır.

Bundan sonraki makalelerde yarattığımız threadleri yönetmek için kullanabileceğimiz metodlara ve threadlerimizi senkronize şekilde çalıştırmak için kullanabileceğimiz yapılara bakacağız.

İyi Çalışmalar,

Onur Ağın
onur@onura.net