Merhaba arkadaşlar bir önceki makalemizde delegate yapısına değinmiştik.
Bu makalede sizlere asenkron
mimari hakkında bilgi vereceğim. Öncelikle asenkron yapısı hakkında
örnekler ile birlikte bir takim açılımlar yapalım.
Kullanmış olduğumuz işletim
sisteminde ayni anda birçok işlemi yapabilme özelliğini asenkron mimari sağlıyor.(Müzik
dinlerken, Word’de makale yazabilir ve MSN’den görüşme yapabilirsiniz.)Düşünsenize
bu saydıklarımın sadece 1 tanesinin kullanılabildiği bir işletim sistemi ne
kadar kötü olurdu… Bir insan vücudunu ele alacak olursak koşarken düşünebilir
el kol hareketleri yapabilir ayni anda da birçok olayi gercekleştirebiliriz.(Asenkron Mimari).
Peki, bunların sadece bir tanesini yapabilir durumda olsaydık? Of bunu hiç düşünemiyorum…
Biraz’da teknik konuşalım. Bir uygulama yapıyorsunuz uygulama ara yüzünde
birçok işlem var(Çalışan listesi, Personel kayıt, arama) Bu 3 yapının ara yüzde
kullanılabilir işlemler olduğunu ve bu işlemleri düz mantık uygulandığını düşünürsek
ara yüz kullanıcısına sabır diliyorum. İşte merak edilen ve saç baş yolduran
uygulamalar düz mantık uygulamalardır. Kullanıcı, Çalışan listesinin dolmasını bekleyene
kadar ne personel kayıt işlemi gerçekleştirebilir nede arama yapabilir. Çünkü uygulama
tek bir process alanına sahip olduğundan dolayı diğer işlemler process alanının
mesguliyetinin bitmesini beklemek zorundadır… (İşlem süresi ne kadar uzunsa,
Bekleme esnasında kullanıcının hakkınızdaki olumsuz düşünceleri o kadar uzun
sürer.)
Peki, bu olumsuz durumlarda kullanıcıyı
zor duruma düşürmeyecek ayni anda birçok işlemi yapabilir hale nasıl
getirebiliriz? Tabiî ki asenkron mimari… Yapıların asenkron çalışması aslında.
NET mimarisinde önemli yere sahip olan Delegate yapısı sağlıyor.(Bir önceki
makalemizde delegate yapısı hakkında bilgi vermiştik)
Delegate’de asenkron mimarilerde önemli pattern yapıları
vardır(Polling, Callback, WaitHandle gibi).
Bu özellikleri sağlayan 3 önemli method vardır
bunlar(Invoke,
BeginInvoke, EndInvoke)
- Invoke:
İşlem tetikler (Senkron olarak çalışırlar)
- BeginInvoke: İşlemleri
tetikler (Asenkron olarak çalışırlar)
- EndInvoke: BeginInvoke yapısının tetiklemiş olduğu işlem sonucunu bekler
Polling: Tetiklenen işlem asenkron
olarak çalışmaya başlar fakat ardından gelen işlemlerin devam edebilmesi için
BeginInvoke tarafından tetiklenen işlem sonucunun gelmesini bekler. Yani şöyle
diyebiliriz.
A (Herhangi bir işlem)
B (A ‘yi tetikleyen Delegate)
C (BeginInvoke) tetiklenir
D (EndInvoke) Sonuç beklenir.
E //İşlem 1
F //İşlem 2
Yukarıdaki tabloda E ve F’nin çalışması
için D’nin sonucu elde etmesi gerekiyor. D sonucu elde elde eder etmez E ve F işlem
yapmaya başlar.
Yönetici tarafından 1. kişiye depodaki ürünlerin miktarının belirlenmesi 2. kişiye eksik ürünlerin tamamlanması görevleri verilsin;
1. Kişi ürün miktarını öğrenmek için yoğun bir şekilde çalışmaya başlar, 2. Kişi
Eksik ürünleri tamamlamak için, 1. Kişinin sayım işlemini bitirmesini ve sonucu
kendisine iletmesini bekler ve almış olduğu sonuç doğrultusunda kendisine yön verir.
Verilen bu iş için Polling Pattern yapısı kullanılmıştır. Simdi bunu
Örneklendirecek olursak.
public delegate int DelegateStokTakip();
private void
Form1_Load(object sender, EventArgs e)
{
DelegateStokTakip d = new
DelegateStokTakip(UrunMiktari);
IAsyncResult sonuc = d.BeginInvoke(null, null);//2 Parametre null olarak verildi.Buraya Callback
Pattern'de deyinecegim.
//BeginInvoke Geriye IAsyncResult Interface'i dönderir.
//EndInvoke
kendisini kullanıma açan delegate geriye dönüş tipini verir.Deleagate int
tipinde deger dönderdigi icin EndInvoke int Tipinde deger dönderir.
int urunMiktari = d.EndInvoke(sonuc);
EksikleriTamamla(urunMiktari);
}
//1.Kisi Urun Miktarini Ögrenir.
int UrunMiktari()
{
int ToplamUrun = 0;
for (int i = 0; i
< 100000; i++)
{
ToplamUrun += i;
}
return ToplamUrun;
}
//2.Kisi Eksik Urun'leri tamamlar.Calişmasi icin 1.Kisi işlemi
bitirmesi gerekiyor.
void EksikleriTamamla(int
UrunMiktari)
{
MessageBox.Show("1.
Kisi Urun Miktarini belirlemiştir.Artik Ben Eksikleri tamamlıyabilirim. Urun
Miktari " + UrunMiktari.ToString());
}
Evet Polling Pattern yönteminde, yapi
her zaman yola devam etmesi için kendisine verilen işlem sonucunu bekler.
CallBack Yöntemi
Kendisine verilen işlemi ayri bir alanda caliştirmaya başlar.İşlem sonucu, proje
akişında hic bir etki alanina sahip degilse
Callback Pattern yöntemi kullanilabilir.
Ayni anda
1’den fazla işlem yürütülebilir(işlem
sonuclari bazi yerleri etkilemiyor ise) Bu
yapiya örnek verecek olursak, Database’de bulunan 1000000 satirlik bir kayit kümesi. Bu sonuc kümesi,
sadece kullanici tarafindan arayuzde görülebilecek ve hic bir işlem akişında
etkili bir role sahip olmayacak. Callback Patterni kullanilarak bu işlem aktif
hale getirilir, kenara atilir ve işlem kenarda devam eder. İşlem ayak altinda
olmaz. Bu işlem devam ederken kod akışına
göre diger işlemler calişmaya başlar.
public delegate
double ToplamDelege();
private void
Form2_Load(object sender, EventArgs e)
{
ToplamDelege d = new
ToplamDelege(Islem);
d.BeginInvoke(new AsyncCallback(CalBack), d);
//Delegate yapisinin tetiklemiş oldugu işlem, AsyncCallback
araciligi ile baska bir alanda caliştirilmasi saglaniyor.işlem baska yerde
sürdürülürken bu noktadan sonra kodun akışı saglaniyor.
HerhangiBirIslem();
}
private void
HerhangiBirIslem()
{
MessageBox.Show("Merhaba
Database'deki veriler gele dursun ben Yoluma devam ediyorum:)");
}
//Başka alanda yürütülen Islem() Methot sonucu bu alanda
yakalanarak proje hangi aşamada olursa olsun bu yapi sayesinde sonucu iletiyor.
void CalBack(IAsyncResult
sonuc)
{
ToplamDelege d = (ToplamDelege)sonuc.AsyncState;
double DonenDeger = d.EndInvoke(sonuc);
MessageBox.Show("Merhaba
Benim işlem Bitti Sonuc : " + DonenDeger.ToString());
}
//AsyncCallback Araciligi ile işlem başka alana transfer
olur.
double Islem()
{
double Toplam = 0;
for (int i = 0; i
< 100000000; i++)
{
Toplam
+= i;
}
return Toplam;
}
Evet Callback Pattern yönteminde yapi işlem sonucuna bakmaksızım yoluna devam eder.
Daha gercekci
bir örnek verecek olursak

Sekik A
Tasarım şekil A 'daki gibidir. Doldur buttonu
tetiklendigi zaman işlem hacmi buyuk olan 2 yapı calısmaya baslıyacaktır. CallBack
pattern yöntemi ile de 2 işlem farkli alanlara cekilerek bagimsız bir sekilde
devam edebilmesini saglayacagiz.
//MusteriGetir iş parcasi
void MusteriGetir(IAsyncResult
r)
{
int toplam = 0;
SqlCommand comm = (SqlCommand)r.AsyncState;
SqlDataReader rdr = comm.EndExecuteReader(r);
while (rdr.Read())
{
lblMusteriler.Text = (toplam++).ToString();
listBox2.Items.Add(rdr["Ad"].ToString());
}
}
//CalisanGetir iş parcasi
void CalisanGetir(IAsyncResult
r)
{
int toplam = 0;
SqlCommand comm = (SqlCommand)r.AsyncState;
SqlDataReader rdr = comm.EndExecuteReader(r);
while (rdr.Read())
{
lblCalisanlar.Text = (toplam++).ToString();
listBox1.Items.Add(rdr["Ad"].ToString());
}
}
private void button1_Click(object
sender, EventArgs e)
{
//MultipleActiveResultSets=true bir connection uzerinde coklu işlem özelligi
saglıyor
//Asynchronous Processing=true Connection uzerinde yapılan
işlemlerin Asenkron yurutulecegini belirtiyorum
SqlConnection conn = new
SqlConnection("Server=.;Database=Portal;MultipleActiveResultSets=true;Integrated
Security=SSPI;Asynchronous Processing=true");
conn.Open();
SqlCommand commMusteri = new
SqlCommand("Select
* From Musteri", conn);
commMusteri.BeginExecuteReader(new AsyncCallback(MusteriGetir), commMusteri);
SqlCommand commCalisan = new
SqlCommand("Select
* From Calisan", conn);
commCalisan.BeginExecuteReader(new AsyncCallback(CalisanGetir), commCalisan);
//Evet Command nesnesinin BeginExeCuteReader yapisi ile
birlikte islemi aktif hale getirecegim.AsyncCallback yapisini kullanarak aktif
hale gelen işlemin kenarda devam etmesini sağliyorum.
MessageBox.Show("O
Calisa Dursun ben Yoluma Devam Ediyorum");
}
sinan.baran@bilgeadam.com
www.sinanbaran.com