Makale Özeti

.Net ile geliştirdiğimiz uygulamalar default olarak tek bir thread üzerinden işlem yaparlar, böyle bir durumda, bir process’in başlatılabilmesi için öncelikle o an çalışmakta olan process’in tamamlanması gerekir. Thread kullanılan uygulamalar da ise, arkaplanda bir işlem çalıştırılırken eş zamanlı olarak kullanıcı arabirimi diğer çağrılara da cevap verir.BackgroundWorker Component asenkron çalışmak için geliştirilmiş bir component'tir.

Makale

BackgroundWorker Component ile Çalışmak

 

.Net ile geliştirdiğimiz uygulamalar default olarak tek bir thread üzerinden işlem yaparlar, böyle bir durumda, bir process’in başlatılabilmesi için öncelikle o an çalışmakta olan process’in tamamlanması gerekir. Thread kullanılan uygulamalar da ise, arkaplanda bir işlem çalıştırılırken eş zamanlı olarak kullanıcı arabirimi diğer çağrılara da cevap verir. Örneğin bir application kendini update ederken update, asenkron olarak yapılıyorsa , güncelleme işlemi esnasında kullanıcı uygulamayı kullanmaya devam eder, aksi halde update işlemi bitene kadar kullanıcı uygulamayı kullanamaz, ve uygulama kilitlenir. Bu sorunları ortadan kaldırmak için Visual Studio .Net 2005 ile birlikte BackgroundWorker adında yeni bir bileşen geldi. Genel kullanım alanlarını aşağıdaki gibi özetleyebiliriz:

·         File system ile çalışırken (File Copy, Image Copy)

·         File download , upload ederken

·         Web services ile çalışırken

·         Büyük database transactionsları esnasında

·         Uzun süren matematiksel işlemler için

BackgroundWorker bileşenini kullanmak için Visual Studio’un Toolbox penceresindeki Components tab’ından BackgroundWorker Component’in forma eklenmesi gerekir.

 

 

BackgroundWorker componentinin 3 adet olayı vardır.

 

·         DoWork

BackgroundWorker ile yapılması istenen işlemler  BackgroundWorker’in DoWork olayında yapılır. BackgroundWorker componentin tetiklenen ilk olayıdır

 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

{

 

}

·         RunWorkerCompleted

BackgroundWorker bileşeninin belirlenen işlemi tamamladıktan sonra RunWorkerCompleted  olayı tetiklenir.

 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

 

}

·         ProgressChanged

BackgroundWorker bileşeninin ReportProgress() metodu çağrıldığında bu olay tetiklenir, böylelikle örneğin arayüzdeki bir ProgressBar kontrolünde  işlem durumu görüntülenebilir. Bu olayın tetiklenebilmesi için BackgroundWorker bileşeninin WorkerReportsProgress özelliğinin True olarak belirlenmesi gerekir

 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

{

 

}

 

BackgroundWorker bileşeninin asenkron işlem yapabilmesi için RunWorkerAsync methodunun kullanılması gerekir. Bu method BackgroundWorker bileşenini başlatır. Bir başka deyişle DoWork olayını tetikler. RunWorkerAsync  optional olarak bir adet parametre bekler ve bu parametre object olarak tanımlanmıştır.  Buraya gönderilen parametre DoWork olayına taşınır ve e.Argument ile  yakalanır.

 

private void btnStart_Click(object sender, EventArgs e)

{

       int number = 52;

       backgroundWorker1.RunWorkerAsync(number);

     

}

 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

{

       int i = (int)(e.Argument);

       MessageBox.Show("Gönderilen Parametre " + i);

}

Backgroundworker bileşeninin DoWork olayında belirlenen işlemler bittiğinde RunWorkerComplated olayı tetiklenir. Bu olay sayesinde Backgroundworker bileşeninin yapması gereken işlemleri bitirdiği yakalanır.

 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

 

}

 

RunWorkerCompleted olayı 2 parametre bekler ve bunlardan ikincisi RunCompletedEventArgs tipinden bir parameterdir. Bu parameter sayesinde işlemin bitiş sonucu, bitiş tipi  veya oluşan hata öğrenilebilir

 

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

        {

                // Eğer hata varsa

                if (e.Error != null)

                {

                    MessageBox.Show(e.Error.Message);

                }

                // Eğer işlem iptal edilmişse

                else if (e.Cancelled)

                {

                    MessageBox.Show("Iptal Edildi");

                }

                // işlem başarılı

                else

                {

                    MessageBox.Show("Islem Başarılı");

                }

 

        }

Bitiş sonucunu öğrenmek için e.Result kullanılmalı.Bu özellik asenkron işlem sonucunu döndürmektedir. :

 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

 

      string msg = String.Format("Sonuc = {0}", e.Result);

      MessageBox.Show(msg);

 

}

 

Çalışmakta olan bir backgroundworker bileşenini iptal edebilmek için bileşenin CancelAsync() methodunun çağırılması gerekir. Bu method çağırıldıktan sonra mevcut işlem için cancellation pending’e haber verir.

 

private void btnCancel_Click(object sender, EventArgs e)

{

      backgroundWorker1.CancelAsync();

}

 

İptal işlemi sadece DoWork olayı içerisinde CancellationPending property’sinin değeri kontrol edilerek yapılabilinir.

 

private void btnStart_Click(object sender, EventArgs e)

{

 

            backgroundWorker1.RunWorkerAsync();      

}

                 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

{

 

            int i = (int)(e.Argument);

 

                // İşlemi İptal Et

            backgroundWorker1.CancelAsync();

 

                  // Bekleyen Cancel Varmi ?

            if (backgroundWorker1.CancellationPending == true)

                e.Cancel = true;

 

            MessageBox.Show("Selaaaaam!!!");

 

}

 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

            if (e.Cancelled)

                MessageBox.Show("Iptal Edildi");

            else

                MessageBox.Show("Islem Başarılı");                  

}

 

Yukarıdaki örnekte btnStart buttonu ile  backgroundworker başlatılmıştır. DoWork olayı içerinde mesaj gösterilmeden hemen önce işlem iptal edilmiş ve CancellationPending property’si ile pending request olup olmadığı kontrol edilmiştir.Mevcut istek olduğu için işlem iptal edilmiş, DoWork olayı içerisindeki mesaj gösterilmemiş, RunWorkerCompleted olayı içerisinden “İptal” mesajı gösterilmiştir.

 

CancelAsync() methodunun çalışabilmesi için bir diğer şart Backgroundworker bileşeninin, WorkerSupportsCancellation özelliğinin True olarak atanmasıdır.

 

Background worker component ile çalışılırken işlemin % kaçının tamamlandığı ReportProgress() methodu ile bildirilir. Bildirim ProgressChanged olayına gönderilir ve bu olay içerisinde e.ProgressPercentage ile gelen parametre alınır.

 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

{

 

           

backgroundWorker1.ReportProgress(30);

            System.Threading.Thread.Sleep(1500);

 

            backgroundWorker1.ReportProgress(45);

            System.Threading.Thread.Sleep(1000);

 

            backgroundWorker1.ReportProgress(100);

}

 

 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

        {

            progressBar1.Value = e.ProgressPercentage;

            this.Text = "%" + e.ProgressPercentage.ToString() + " tamamlandı";

          

        }

 

Bir başka makalede görüşmek üzere

 

Okan Tekeli

 

okan.tekeli@bilgeadam.com

okan@okantekeli.com