Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C# İle Multi Thread Programlamada System.Threading.Thread Sınıfı

Merhaba,

Multi Thread Programlama Yazı Dizisinin artık programatik kısmına gelmiş bulunmaktayız. .NET platformunda yapılacak olan tüm Multi Thread programlama işlemlerini System.Threading.Thread sınıfı ile gerçekleştirmekteyiz. Haliyle bu içeriğimizde bu sınıfı a’dan z’ye inceleyeceğiz.

Thread Yaratılması

Thread sınıfından üretilen her nesne ile aslen bir thread oluşturmuş oluyoruz.

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread t1 = new Thread(Fonksiyon);
        }

        void Fonksiyon() {
            int Sayac = 0;
            while (true)
            {
                Sayac++;
                this.Text = Sayac.ToString();
            }
        }

Gördüğünüz gibi Fonksiyon isimli metodu t1 referanslı bir Thread nesnesi aracılığıyla farklı bir thread da çalıştıracağız.

Start Metodu

Oluşturduğumuz Thread’ı çalıştıracak, bir başka deyişle işleyecek metotdur.

            Thread t1 = new Thread(Fonksiyon);
            t1.Start();

Abort Metodu

Çalışan Thread’ın programatik olarak durdurulması yani çizelgeleme dışına çıkartılması için kullanılır. Lakin çağrıldığı anda hemen threadın çalışmasını durdurmaz. Bunun sebebi, Start metodu gibi asenkron bir şekilde çalışmasıdır.

Unutmayın ki, bir threadın gerçek manada durdurulması için o threadın üzerinde çalıştırılan fonksiyonun Safe Point olarak nitelendirilen güvenli bir noktaya ulaşması gerekmektedir. Bu nokta genellikle Garbage Collection mekanizmasının devreye girdiği andır.

Abort metodu ile durdurulmuş bir Thread, Start metodu ile tekrardan başlatılamaz.

Suspend ve Resume Metodu

Suspend metodu ile Thread geçici olarak durdurulabilir. Yani çizelgeleme dışına çıkartılabilir. Suspend ile geçici olarak durdurulmuş Thread Resume metodu ile kaldığı yerden devam ettirilebilir.

        Thread t1;
        private void Form1_Load(object sender, EventArgs e)
        {
            t1 = new Thread(Fonksiyon);
            t1.Start();
        }
        void Fonksiyon()
        {
            int Sayac = 0;
            while (true)
            {
                Sayac++;
                this.Text = Sayac.ToString();
            }
        }
        private void btnSuspend_Click(object sender, EventArgs e)
        {
            t1.Suspend();
        }
        private void btnResume_Click(object sender, EventArgs e)
        {
            t1.Resume();
        }

Burada dikkatinizi çekerim ki, Multi Thread yaklaşımlarda bu iki metodun kullanımından mümkün mertebe kaçınmanızı tavsiye ederim. Bunun nedeni, Suspend ile durdurulmuş bir threadın diğer threadlar ile paylaşımlı olarak kullandığı kaynaklarda çıkardığı Deadlock diye nitelendirdiğimiz muhtemel sorunlardır.

Deadlock Nedir?

Hemen yeri gelmişken Deadlock üzerine biraz konuşalım.
Deadlock aslında processlerin hiçbir zaman ulaşamayacakları bir birim yahut kaynağa ihtiyaç duymaları durumudur. Durum böyle olunca processlerin askıda kalmaları diye özetleyebiliriz. Yani bir processi askıda bırakacak her işlem olası deadlock durumuyla karşılaşmamızı sağlayabilir. Örneğin; bir process bir diğer processin işini bitirmesini beklerken aynı şekilde o processinde diğer processin işini beklemesi durumudur. Yani çıkmaza girmektir.

Hani en kötü 90’lılar hatırlarlar. Bilgisayarlarımız durmadan takılırdı da ayak topuğuyla monitörden acısını çıkarırdık. İşte aslında o takılma değil, kilitlenmeydi. O kilitlenme de deadlock’tan kaynaklanmaktaydı. Deadlock’tan kaçış için onlarca algoritma olmasına rağmen bir şekilde yakalanılır ve en etkili çözüm olarak reset tuşu kullanılırdı… 🙂

Sleep Metodu

Aslında bizlere fazla yabancı olmayan Sleep metodu, teknik olarak aldığı milisaniye cinsinden değer kadar threadı durdurmamızı sağlayan(çizelgeleme dışına çıkartan) static bir metotdur.

Burada dikkat etmeniz gereken nokta, Sleep metoduna verilen süre sonunda thread tekrar devreye giremeyebilir. Bunun nedeni, Win32 sistemlerinin Real Time(Gerçek Zamanlı) işletim sistemleri olmayışıdır.

        void Fonksiyon()
        {
            int Sayac = 0;
            while (true)
            {
                Thread.Sleep(1000);
                //Bir saniye boyunca bu thread çizelgeleme dışına çıkarılacaktır.
                Sayac++;
                this.Text = Sayac.ToString();
            }
        }

Ayriyetten Sleep metoduna -1 değerini verirseniz ilgili thread belirsiz süreliğine durdulacaktır.

                    Thread.Sleep(new TimeSpan(0, 1, 1));

Yukarıdaki gibi TimeSpan ile kullanırsak eğer 0 saat, 1 dakika ve 1 saniye gibisinden zaman zarfı belirleyebilir, threadı daha net zamanlayabiliriz.

Ayrıca Sleep metoduna verilen 0 değeri, söz konusu threadın çizelgeye girme hakkını diğer threadlara devretmesini sağlar.

Join Metodu

Düşünün ki, bir threadı sonlandırmak istiyorsunuz ama ilgili thread içerisinde kullanılan diğer threadların son bulması şartıyla…

İşte Join metodu bu işlevi görmektedir.

        static void Main(string[] args)
        {
            Thread t1 = new Thread(Fonksiyon);
            t1.Start();

            while (!t1.Join(5000))
                Console.WriteLine("Denetleniyor");
            Console.WriteLine("Denetlenme tamamlandı. Thread sonlandı.");

            Console.Read();

        }

        static void Fonksiyon()
        {
            int Sayac = 0;
            while (Sayac < 100)
            {
                Sayac++;
                Thread.Sleep(500);
            }
        }

Verilen süre periyodunda threadı kontrol eden ve geriye durumla ilgili bool bir değer döndüren Join metodunu yukarıdaki gibi while döngüsü aracılığıyla kullanarak ilgili threadı takip edebilir ve işlemlerimizi gerçekleştirebiliriz.

C# İle Multi Thread Programlamada System.Threading.Thread Sınıfı

ThreadState Propertysi

İlgili threadın herhangi bir T anındaki durumunu bizlere vermektedir.

Priority Propertysi

Threadın öncelik düzeyinin belirlenmesini sağlar. Varsayılan olarak Normal değerine sahiptir.

IsAlive Propertysi

Threadın herhangi bir T anında aktiflik durumunu verir.

Bu son satırlada Multi Thread işlemleri gerçekleştirmemizi sağlayan Thread sınıfını bitirmiş bulunmaktayız. Sonraki yazılarımızda seriye katkıda bulunacak bir çok konuyu ele alacak ve içeriklerini net bir şekilde oluşturacağız…

Şimdilik görüşmek üzere…

İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

10 Cevaplar

  1. Adil dedi ki:

    Merhaba,join orneyinde while dongusundeki sart !t1.join(5000) ne anlama geliyor??

  2. Agit dedi ki:

    merhaba. elinize ve emeğinize sağlık. Bu seri ile ilgili başka makaleler oldu mu ben bulamadım.

    • Gençay dedi ki:

      Merhaba,

      Üzgünüm ama bu makale sonuncudur. Çok uzak olmasa da ileride youtube kanalında MultiThread&Asenkron programlamaya dair a’dan z’ye ücretsiz içerikler paylaşacağım.
      Bilginize.
      Kolay gelsin…

  3. Onur SARI dedi ki:

    Merhaba Gençay hocam,

    Bir projemde thread kullanmaya çalışıyoru. Her şey doğru görünüyor fakat sleep metodunu açıklarken belirttiğiniz gibi thread yeniden devreye girmiyor. Bu problemi nasıl çözebileceğim hakkında yardımcı olabilirseniz çok sevinirim.
    Saygılar,

    • Gençay dedi ki:

      Merhaba,

      İlk fırsatta göz atacağım. Eğer siz çözüm bulursanız lütfen bizimle paylaşınız.
      Kolay gelsin.

      • Onur SARI dedi ki:

        Tekrardan merhaba,

        Sorumu sorduktan sonra thread konusunu araştırmaya devam ederken aslında yaptığım bir yanlışın farkına vardım. Ben thread’i aktif ederken çalıştırdığım metodun içerisine sürekliliği sağlayacak bir fonksiyon yazmamışım. Yani sizin örneğinizdeki Fonksiyon() isimli metodun içerisindeki 100 tekrarlı while döngüsü gibi bir döngü gerektiğini atlamışım. Ben periyodik olarak PLC içerisinden veri okuma yapmak istediğim için çalıştırdığım metodun içerisine while(true) şeklinde bir döngü koyduğumda problem çözülmüş oldu.

        Teşekkür ediyorum. 🙂

Agit için bir yanıt yazın Yanıtı iptal et

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir