WaitOne Tekniği
Bu tekniğimizde uygulama tek bir SQL komutu için bekletilir. Bu aşamada bu tekniği sadece bir cümle ile açıklayıp hemen örneğimiz üzerinden ilerleyelim. Örneğimizde veritabanımızdaki iki ayrı tabloda güncelleme yapıyor ve bu işlemlerden birinin erken bitmesine rağmen diğerini beklediğini görüyor olacağız.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
namespace Wait_One
{
class Program
{
static void Main(string[] args)
{
//SqlConnection nesnelerimizi oluşturuyoruz.
SqlConnection con1 = new SqlConnection("data source=.;initial catalog=AdventureWorks; integrated security=true;async=true");
SqlConnection con2 = new SqlConnection("data source=.;initial catalog=AdventureWorks; integrated security=true;async=true");
//SqlCommand nesneleri aracılığıyla sorgu ifadelerimizi yazıyor ve birini 10,diğerini 20 saniye bekletiyoruz.
SqlCommand cmd1 = new SqlCommand("waitfor delay '0:0:20'update Person.Contact set FirstName=FirstName", con1);
SqlCommand cmd2 = new SqlCommand("waitfor delay '0:0:10'; update HumanResources.Employee set Title=Title", con2);
//Baglantilarımız açıyoruz.
con1.Open();
con2.Open();
//Asenkron işlemimizin toplam ne kadar sürdüğünü görebilmek için uygulama başlar başlamaz bir DateTime tanımlıyoruz ve uygulamanın başladığı anın değerini alıyoruz.
DateTime simdi = DateTime.Now;
//Asenkron çalışacak işlemlerimiz.Fakettiğiniz üzere senkron işleyişten farklı olarak SqlCommand nesnelerinin metotlarının başında Begin ve End ifadeleri yer alıyor.
IAsyncResult res1 = cmd1.BeginExecuteNonQuery();
IAsyncResult res2 = cmd2.BeginExecuteNonQuery();
//Iki SqlCommand birbirlerini beklemesi için :
res1.AsyncWaitHandle.WaitOne();
res2.AsyncWaitHandle.WaitOne();
//Güncellemeler sonucu etkilenen kayıt sayısını alıyoruz.
int etkilenen = cmd1.EndExecuteNonQuery(res1);
int etkilenen2 = cmd2.EndExecuteNonQuery(res2);
//Uygulamamızın bittiği anın değerini alıyoruz.
DateTime sonra = DateTime.Now;
//Baglantıları kapatıyoruz.
con1.Close();
con2.Close();
//Ekrana Yazdırıyoruz.
Console.WriteLine("Person.Contact Tablosunda {0} kayit güncellendi..", etkilenen);
Console.WriteLine("Human Resources Employee Tablosunda {0} kayit güncellendi", etkilenen2);
//Uygulamanın son anından ilk anın çıkarıp geçen süreyi hesaplıyoruz ve ekrana gösteriyoruz.
TimeSpan fark = sonra - simdi;
Console.WriteLine("Gecen Zaman : {0}", fark.TotalSeconds);
}
}
}
Uygulamamızı çalıştırıp sonucu görüyoruz.

Gördüğümüz gibi iki sonucumuzda aynı anda başladı ve ilk biten işlemimiz diğer SQL komutunu da bekledi ve sonuç olarak iki işlemimizde aynı anda ekrana geldi. Uygulamanın toplam çalışma zamanı olan 20 saniye de geç bitmesi için bizim manuel olarak beklettiğimiz işlemin süresidir.
WaitAll Tekniği
Bu tekniğimiz adından da anlaşıldığı üzere tüm işlemlerin bitmesinin beklendiği hepsinin aynı anda bitirildiği tekniktir. Bu uygulamamıza ait örneğimizle tekniğimizi incelemeye başlayalım.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Threading;
namespace WaitALL_Teknigi
{
class Program
{
static void Main(string[] args)
{
string conStr = "data source=.;initial catalog=AdventureWorks;Integrated security=true;async=true";
//Baglantılar
SqlConnection con1 = new SqlConnection(conStr);
SqlConnection con2 = new SqlConnection(conStr);
SqlConnection con3 = new SqlConnection(conStr);
//SQLCommand ifadeleri
SqlCommand cmd1 = new SqlCommand("waitfor delay '0:0:20';select Name from Production.Product", con1);
SqlCommand cmd2 = new SqlCommand(" waitfor delay '0:0:10';update Production.Product set Color='Black' where Color='Siyah'", con2);
SqlCommand cmd3 = new SqlCommand("waitfor delay '0:0:5';update Person.Contact set FirstName=FirstName", con3);
con1.Open();
con2.Open();
con3.Open();
DateTime once = DateTime.Now;
//Asenkron Isleyis
IAsyncResult res1=cmd1.BeginExecuteReader();
IAsyncResult res2 = cmd2.BeginExecuteNonQuery();
IAsyncResult res3 = cmd3.BeginExecuteNonQuery();
//WaitHandle.WaitAll() metodunu bizden isteyecegi ve hangi uygulamanin bittigi bilgisinin kontrol edilmesini yardimci dizimiz.
WaitHandle[] handler = new WaitHandle[] { res1.AsyncWaitHandle, res2.AsyncWaitHandle, res3.AsyncWaitHandle };
WaitHandle.WaitAll(handler);
// Asenkron Başlatilan Islemleri Teker Teker Alalim
SqlDataReader dr=cmd1.EndExecuteReader(res1);
while (dr.Read())
{
Console.WriteLine(dr.GetString(0));
}
dr.Close();
con1.Close();
// Ikinci Asenkron Başlatilan Islemin Sonucunu Alalim
int etkilenen1=cmd2.EndExecuteNonQuery(res2);
Console.WriteLine("--------------------------------------------------------------");
Console.WriteLine("Production.Product Tablosunda {0} kayit etkilendi", etkilenen1);
Console.WriteLine("--------------------------------------------------------------");
con2.Close();
// Ucuncu Asenkron Başlatilan islemin sonucunu alalim
int etkilenen2 = cmd3.EndExecuteNonQuery(res3);
Console.WriteLine("--------------------------------------------------------------");
Console.WriteLine("Person.Contact Tablosunda {0} kayit etkilendi", etkilenen2);
Console.WriteLine("--------------------------------------------------------------");
con3.Close();
DateTime sonra = DateTime.Now;
TimeSpan fark = sonra - once;
Console.WriteLine("Gecen Zaman {0} saniyedir", fark.TotalSeconds);
}
}
}
Son olarak sonucumuza da bir göz atalım.

Üç işlemimizde farklı sürelerde bitmesine rağmen son biten işlemi de bekleyip hep birlikte ekrana geldiler. Uygulamanın çalışma süresi de doğal olarak son biten işlemin süresine denk oldu. Bu teknikte bir uygulamanın bir fazla thread ile çalışması ve kullanıcıyla işlemlerin sonucunun aynı anda gösterilmesi istenilen durumlarda kullanılabilecek bir tekniktir.
Asenkron programlamanın iki tekniği incelemeye çalıştıktık. Bir sonraki makalemizde diğer teknik olan CallBack ve Pooling tekniklerini de inceleyerek Asenkron Programlama konusu bitirmiş olacağız.
Faydası olması Dileğiyle.
Herkese İyi Çalışmalar.