Selam herkese , öncelikle herkesin mevlid kandilini kutlarım.
Bugün asenkron mimarisini inceleyeceğiz inş.
Asenkron mimari nedir ?
Süreçlerin bağımsız bir şekilde aynı anda devam etmesi şeklinde yorumlanmaktadır.
C# da asenkron mimari yapısını uygulamak için genel anlamda kullanılan iki ana yapı mevcuttur.
- Thread Sınıfı
- Asenkron Metodlar (BeginInvoke, Stream.BeginRead vb)
Bilgisayarlar aynı anda birden fazla işlem yapamaz, nasıl yapamaz ? Şöyle ki ; Biz her ne kadar word de bir yazı yazıyor ve winampta şarkı dinliyorken her iki işlemi biz her ne kadar aynı anda yapıyormuş gibi algılasakta değildir, yaptığımız bu işlemler sırasıyla yapılmaktadır. Toplam işlemler iş parçacıklarına bölünerek sırasıyla yapılır.
Bizde normal şartlar altında bir müdahelede bulunmadığımız sürece programlarımız senkron çalışır, yani kodu okur görevini yerine getirdikten sonra bir alt satırdaki kod ile devam eder. Asenkron programlama ile biz programımız bir şeyi yaparken onunla beraber başka şeyler yapmasını isteriz. Bunuda işlemleri parçacıklara bölerek gerçekleştirir bir ondan bir bundan, bir ondan bir bundan ![]()
while (DateTime.Now.Second != 30)
{
this.Text = DateTime.Now.Second.ToString();
}
MessageBox.Show("Test");
Burada saniye 30 olduktan sonra döngüden çıkılacaktır, biz bunu beklemek zorunda değiliz bu yüzden hem metodu hemde uyarıyı aynı anda çalıştırmak isteriz.
Önce asenkron metodlardan başlamak istiyorum.
Asenkron Metodlar
Bu yöntemde biz delegate kullanacağız.
Programımızda butona bastıktan sonra Test diye uyarı versin ve formun başlığını her saniye değiştirsin.
Döngü içerisindeyken çalıştırmak istediğimiz metodun içeriği aşağıdaki şekilde olsun;
while (DateTime.Now.Second != 30)
{
this.Text = DateTime.Now.Second.ToString();
}
Şimdi delegate i tanımlayalım;
public delegate void IslemHandler();
Butonun click olayına aşağıdaki kodları yazalım;
private void button1_Click(object sender, EventArgs e)
{
IslemHandler islem = new IslemHandler(metodumuz);
islem.BeginInvoke(new AsyncCallback(islemSonlandi), this);
}
Burada BeginInvoke metodu ile gerçekleştiriyoruz yapmak istediğimizi, bu metodu kullanırken bizden AsyncCallback türünde bir delegate istiyor, biz delegate i metod içerisinde kuruyoruz, kurduğumuz bu metod içerisinde bizden IAsyncResult türünde bir parametra alan ve geri dönüş tipi void olan bir metod istemektedir, istemesinin nedeni de şu ; bu işlem parçacığı bittiği zaman belirttiğimiz bu metod çalışacaktır, bu yüzden bu tanımlamayı yaparken ek olarak bir metod yazmamız gerekecek, mesela işlem bittiğinde “İşlem bitti” diye uyarı versin.
2. istediği bir parametre ise object türünde herhangi birşey, null olarak ta gönderebilirdik ama ben formun o anki başlığını ekrana yazdıracağım bu yüzden formun kendisini gönderdim.
void islemSonlandi(IAsyncResult ia)
{
Form1 frm = (Form1)ia.AsyncState;
MessageBox.Show(frm.Text + "\nİşlem sonlandı");
}
Bizden object türünde bir nesne istemişti ve biz this yani formun kendisini göndermiştk, ia.AsyncState ile bize gelen nesneye ulaşıyoruz, yani AsyncState metodu bize BeginInvoke ile gönderdiğimiz nesneyi geri gönderiyor.
Son olarak ta formun load olayına aşağıdaki kodu yazıyoruz ;
CheckForIllegalCrossThreadCalls = false;
Eğer bunu yazmazsak yaptığımız işlemler çalışmayacak ve hata verecektir. program.cs içerisinde Application.Run(new Form1); ile formu çalıştıran bir process var, normalde aynı anda iki process aynı şeyi kullanamaz biz yukarıdaki tanımlamayı yaparak bunu yoksaymasını istiyoruz.
Programı çalıştırıp butona bastığımızda hem uyarı verip hemde formun başlığının değiştirildiğini göreceksiniz. Ve işlem bittiğinde ayrı bir uyarı.
Projeyi en altta verdiğim linkten indirebilirsiniz.
Thread Sınıfı
Thread sınıfının kullanılması daha hoş. Thread, iş parçacıklarıdır.
Çalıştırmak istediğimiz metod ;
void islemYap()
{
while (DateTime.Now.Second != 52)
{
this.Text = DateTime.Now.ToString();
}
}
Buton click olayına da aşağıdaki kodu yazıyoruz;
Thread islem = new Thread(new ThreadStart(islemYap));
islem.Start();
Burada Thread sınıfından yararlanıyoruz, Thread sınıfını kurarken constructor olarak ThreadStart sınıfı istiyor ve ThreadStart sınıfı da çalıştırmasını istediğimiz metodu istiyor
Thread çok kapsamlı, çok pratik yapılması gereken bir konu. Özünde AsynCallback temelini kullanan bir yapı.
Thread sınıfı içerisinde güzel metodlar var birkaçı ;
Suspend : işlemi dondurur.
Resume : dondurduğumuz işlemi devam ettirir.
Priority : işlemin önceliğini arttırır azaltabilmemiz için kullanılan ayrı bir metod.
Proje içerisinde ayrı birkaç şey açıkladım.
[PROJE]
Okula gitmek zorundayım sanırım 5-10 dk geç kaldım ![]()
Hayırlı çalışmalar dilerim.
CheckForIllegalCrossThreadCalls = false; kullanman pek doğru bir yaklaşım değil , bu şekilde thread exceptionlarını görmezden gel diyorsun.
Eğer Control objeleri farklı kanallardan aynı Control objesine erişmek isterse normalde exception gönderir ve bu durumda sen false yaptığın için bunu göremiyeceksin. Buda aslında yazdığın kodun thread safe çalışıyacağı anlamına gelir.
Aslında thread senkronizasyonu ile doğru bir şekilde çalışmayı anlatmış olsan daha iyi olurdu. Bilgine.