Bu yazımda C#’ta Asenkron mimarisini inceleyeceğiz.Bir program akışında bir işlem bitmeden başka bir işlem yapılmaz.Asenkron mimari bize, süreçlerin birbirinden bağımsız aynı anda çalışmasını sunuyor.C#’ta Asenkron mimarisini uygulamak için iki yapı mevcuttur.Bunlardan biri Asenkron Metodlar (BeginInvoke, Stream.BeginRead vb..) diğeri Thread Sınıfıdır.Bu yazımda sizlere Asenkron metodları göstereceğim.
Öncelikle mevzuyu daha derinlemesine açıklamak istiyorum.Aşağıdaki kodları inceleyiniz.
while (true)
{
}
MessageBox.Show("Test");
Yukarıdaki işlem Senkron çalıştığı için sonsuz döngü bitmediği taktirde “Test” mesajını görmemiz mümkün olmayacaktır.Sonsuz döngüyü ve “Text” mesajını Asenkron çalıştırdığımız taktirde ikiside aynı anda çalışabilir hale gelecektir.Yani birbirlerinden bağımsız çalışacaklardır.
Değişik komut bloklarını aynı anda asenkron çalıştırmak için delegelere başvururuz.
Şimdi aşağıdaki kodları inceleyiniz.
void X()
{
while (DateTime.Now.Second != 20)
{
this.Text = DateTime.Now.Second.ToString();
}
}
private void button1_Click(object sender, EventArgs e)
{
X();
}
buton1 isimli nesneye tıkladığımız zaman X metodu devreye girecektir.Formun Text’inde saniyeleri göreceğiz ama formu hareket ettiremeyeceğiz,kapatamayacağız ya da başka bir işlem yapamayacağız.Çünkü bu yapılmaya çalışılan işlemlerin hepsi(sürükleme,kapatma vs),sonuçta programımızın while döngüsü bitmeden gerçekleştirilemeyecektir.Bunun sebebi yukarıda X medotu içindeki while döngüsü senkron çalışmaktadır ve kendisinin çalışması bitmeden,başka işleme izin vermiyor.
Şimdi Asenkron mimariyi kullanma zamanı.X metodunu asenkron olarak çalıştıralım.
Yukarıdaki kodlara bir + olarak delegate koduda ekleyip aşağıda yayınlıyorum.
delegate void AsenkronHandler();
void X()
{
while (DateTime.Now.Second != 20)
{
this.Text = DateTime.Now.Second.ToString();
}
}
private void button1_Click(object sender, EventArgs e)
{
X();
}
Şimdi bu delegemizden bir nesne oluşturup,X metodumuzu bu delegeye işaret ettirelim.
AsenkronHandler asenkron = new AsenkronHandler(X);
asenkron(); //Böyle çalıştırırsam da senkron çalışır.
asenkron.Invoke(); //Böyle çalıştırırsam da senkron çalışacaktır.
Yukarıda gördüğünüz gibi bir tek delegeyle metodu çalıştırmak Asenkron çalıştırmaya yetmiyor.Peki ne yapmamız lazım.
AsenkronHandler adında delegate nesnesinin “Begin” ile başlayan metodları, asenkron çalıştırma yapabilmek içindir.
BeginInvoke() Metodu :
BeginInvoke() metodu ile, delegemizin işaret ettiği metodu asenkron çalıştırmış oluyoruz.Burada BeginInvoke() metodu bizden AsyncCallback delegesi aracılığıyla çalıştırılacak bir metod istiyor.Bunu istemesinin sebebi şudur ;
Delegemizin çalıştırdığı metodun işi bittiğinde biz programcı olarak o işin bittiğinden haberdar olmak isteyebiliriz.Burada AsyncCallback delegesinin çalıştıracağı metod,delegemizin çalıştıracağı metodun işi bittiği zaman devreye girer(Otomatik olarak).
BeginInvoke() metodu bizden 2. olarak object bir değer ister.Bizim buna vereceğimiz değer AsyncCallback delegesinin çalıştırdığı metodun IAsyncResult tipinden tanımlanmış parametresine gönderilir.
Şimdi yukarıda anlattıklarımı kodlarda görelim.
private void button1_Click(object sender, EventArgs e)
{
AsenkronHandler asenkron = new AsenkronHandler(X);
asenkron.BeginInvoke(new AsyncCallback(Y), this);
/*BeginInvoke metodu 1. parametresinde, AsyncCallback delegesinden, geriye dönüş
tipi olmayan ve IAsyncResult tipinden parametre alan bir metod istiyor.
IAsyncResult tipinden parametre alan Y() metodunu yazıp ben BeginInvoke
metodunun 1. parametresine gördüğünüz gibi yazıyorum.2. parametresine ise,
this(yani bu formu) gönderiyorum.Buraya gönderilen object değer,Y metodunun
IAsyncResult tipinden olan dd adlı parametresine gönderilecektir.
*/
}
void Y(IAsyncResult dd)
{
/*Bu metoddaki IAsyncResult tipinden dd parametresine gelen değer,
AsyncState özelliğinden elde edilebilir.*/
}
Şimdi programımızı derleyip çalıştırırsak eğer,buton1’e tıkladığımızda aşağıdaki hatayla karşılacağız 🙂
“Cross-thread operation not valid: Control ‘Form1’ accessed from a thread other than the thread it was created on.”
Bu hata,threadlardan oluşuyor.Threadler çakışıyor.
Formun loadına, ya da button1 in Click özelliğinin ilk satırına şu kodu yazarsanız hata vermeyecektir.
CheckForIllegalCrossThreadCalls = false; /*"Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on." hatası vermemesi için yazılır.Threadlerin çakışmasını engeller.*/
Son olarak programımızı derleyip çalıştırdıktan sonra, formumuzun Text’inde saniyeleri görürken, formumuzda başka işlemler yapabileceğiz(kapat,büyüt,küçüt,taşı vs.).Artık X metodundaki while döngüsü Senkron değil Asenkron çalışmaktadır.Asenkron while döngüsü bitmeden , ondan bağımsız diğer işlemlerimizide gerçekleştirebiliyoruz.
İşte bu şekilde Asenkron çalışıp, aynı anda birden fazla işlem yapabilirsiniz..
Bir sonraki yazımda görüşmek üzere..
İyi çalışmalar.