Web Sayfalarında Asenkron Veri Çekme

Web Sayfalarında Asenkron Data Çekme

Web Sayfalarında Asenkron Data Çekme

Yapmış olduğumuz web sayfalarında asenkron işlemleri kullanarak daha hızlı ve verimli çalışmasını sağlayabiliriz. Örnek bir durum olarak şu şekil bir seneryoyu düşünebilirsiniz. Sayfanız üzerinde 4 adet giridview var ve bu girdviewler ayrı database yada ayrı tablolardan kayıtları kullanıcıya gösteriyor. Tabiki bu dolan Gridview lerin hepsi aynı zamanda dolmuyor. Birinci Gridview in DataTable ‘i beş sn. İkinici Gridview’in DataTable’i on saniye, üçüncü ve dördüncü Gridview’in DataTable i da 20 sn sürdüğünü düşünelim. Standart olarak yaptığınız işlemlerde Web Formun Load olayına Gridview1 i dolduran, Gridview2’yi dolduran ,Gridview3 ve Gridview4 ü dolduran metodları çağrırız. Bu işlemler senkron çalışacağı için sırayla görevlerini yaparlar, görevleri bitikten sonra yani dört DataTable dolduktan sonra yaklaşık olarak 55 sn. kadar süren bu işlemler sırasında, sizin sitenizi ziyaret eden kullanıcılar da değerleri ekranda görmek için sizi bekleyeceklerdir. Bu işlemler özellikle, beklemek sıkıcı olacağından dolayı ziyaretci kaybına neden olacaktır.

Sayfanızı açtığınızda aşağıdaki gibi bi görüntü olduğunu düşünün 4 ayrı Gridview.

Bu Gridviewleri doldurmak için aşağıdaki gibi bir yöntemi uygularsanız.

protected void Page_Load(object sender, EventArgs e)

{

if (this.IsPostBack) return;

Doldur1();

Doldur2();

Doldur3();

Doldur4();

}

Bu işlemler senkron çalıştığı için işlemler teker teker çalışıp biri bitince diğeri başlayacak ve en sonuncu bittikten sonra sayfanız yukarıdaki gibi gürünecektir.

Bu şekilde istenmiyen bir durumu ortadan kaldırmak için yapılabilecek çözümlerden bir tanesini birlikte uygulayacağız.

Bir Gridview’i doldurmak için şöyle bir kod uyguladığımızı düşünelim.

void Doldur1(object nesne)

{

SqlConnection con = new SqlConnection("server=.\SQlExpress;database=DryCleaners;User Id=sa;Password=1");

SqlDataAdapter da = new SqlDataAdapter("Select top 10 * from Urunler", con);

DataTable dt = new DataTable();

da.Fill(dt);

GridView1.DataSource = dt;

GridView1.DataBind();

}

Vede Form Load da bu şekilde çağrıyorsunuz.

protected void Page_Load(object sender, EventArgs e)

{

if (this.IsPostBack) return;

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur1), null);

}

Şimdi hepimizin bildiği gibi Asp.Net sayfaları ve IIS in çalışma prensibine göre, siz istemci olarak (Web Browser) karşı taraftan (bir Sunucudan) bilgi istersiniz, o da size HTML olarak datayı gönderir. Buradaki altın kural sadece istemci , karşıdan bilgi isterse sunucu ona bilgiyi gönderir. Sayfadaki HTML çevrimi bittikten sonra sunucudaki değişimler istemci tarafından algılanamaz.

Eğerki siz Formun Load metodunda Doldur1 adlı metodu Thread ile çağrırsanız sayfanız istemciye ulaşır, Thread arka planda işlemini bitirir ve sayfa istemciye çoktan gittiği için siz Gridview’inizde birşey göremezsiniz.

Burdan çıkaracağımız sounç Threadler işini bitirseler dahi siz sayfanızı aldığınız için sonucu göremezsiniz. Demek oluyorki Thread işini bitirdiği zaman sizin istemciden , sunucuya bu konu ile ilgili bir istek göndermeniz gerekiyor. İşte bu istekleri Ajax teknolojisini kullanarak Gridviewleri ayrı ayrı ekranda göstereceğiz.

Aşağıdaki gibi 4 adet Updatepanel ve bunların içlerinde timerlar yardımı ile Gridviewleri dolduruyoruz.

Yukarıdaki resimde bulunan şekle benzer bir dizayn oluşturuyoruz.

UpdatePanellerin UpdateModlarini Conditional olarak ayarlıyoruz.

Timerlerin Intervalları 1000 (milisaniye) olarak ayarlanıyor.

Timerların görevi saniyede bir threadlerin işlerini bitirip bitirmediğini kontrol etmektir. Bunuda yaparken şu yolu izliyoruz. Timer Session içerisinde adı ‘d1’ (her bir timer farklı bir Session değerine bakacaktır.) olan bir değerin oluşup oluşmadığına bakıyor ve oluşmuşsa bunu (Session içinde DataTable var) Gridview e bağlıyor. Daha sonra kontrol etmeyi bırakıp Session’a null değer atıyoruz.

protected void Timer1_Tick(object sender, EventArgs e)

{

if (Session["d1"] != null)

{

GridView1.DataSource = (DataTable)Session["d1"];

GridView1.DataBind();

Timer1.Enabled = false;

Session["d1"] = null;

}

}

Şu anki kodlara göre Formun Load metodu bu şekilde oluturuyor.

protected void Page_Load(object sender, EventArgs e)

{

if (this.IsPostBack) return;

Session.Add("dr1", "");

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur1), Session);

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur2), Session);

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur3), Session);

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur4), Session);

}

Threadlere gönderilen Session parametresi aracığı ile Thread içinde o an kullanılan Session a ulaşıp DataTable ‘ı belirtilen ‘d1’ gibi bir isimle saklıyor.

void Doldur1(object durum)

{

HttpSessionState s = (HttpSessionState)durum;

SqlConnection con = new SqlConnection("server=.\SQlExpress;database=DryCleaners;User Id=sa;Password=1");

SqlDataAdapter da = new SqlDataAdapter("Select top 10 * from Urunler", con);

DataTable dt = new DataTable();

da.Fill(dt);

s["d1"] = dt;

}

Program ilk çalıştığında ekrana boş bir sayfa geliyor. Bu anda aslında arka planda veritabanlarından datalar çekilip DataTablelar dolduruluyor ve Timerlarda bu işin bitip bitmediğini Session aracılığı ile kontrol ediyor. Thread işini bitirdiğinde Session’a değerini göderiyor, Timerda alıp Gridview ‘e bağlayıp ekranda gösteriyor. Böylece ekranda işler bittikçe gözüküyor, kullanıcı tüm işlerin bitmesini beklemeden işlemlerden hangisi önce biterse o kaydı inceleme fırsatı buluyor.

Aşağıdaki gibi işlem bitiş sıralarına göre parçalar halinde ekrana gelecektir.

Bu kısımda da Tüm kodları gönderiyorum.

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Data.SqlClient;

using System.Web.SessionState;

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

if (this.IsPostBack) return;

Session.Add("dr1", "");

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur1), Session);

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur2), Session);

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur3), Session);

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Doldur4), Session);

}

protected void Timer1_Tick(object sender, EventArgs e)

{

if (Session["d1"] != null)

{

GridView1.DataSource = (DataTable)Session["d1"];

GridView1.DataBind();

Timer1.Enabled = false;

Session["d1"] = null;

}

}

void Doldur1(object durum)

{

HttpSessionState s = (HttpSessionState)durum;

SqlConnection con = new SqlConnection("server=.\SQlExpress;database=DryCleaners;User Id=sa;Password=1");

SqlDataAdapter da = new SqlDataAdapter("Select top 10 * from Urunler", con);

DataTable dt = new DataTable();

da.Fill(dt);

s["d1"] = dt;

}

void Doldur2(object durum)

{

System.Threading.Thread.Sleep(6000);

HttpSessionState s = (HttpSessionState)durum;

SqlConnection con = new SqlConnection("server=.\SQlExpress;database=DryCleaners;User Id=sa;Password=1");

SqlDataAdapter da = new SqlDataAdapter("Select top 10 * from KullaniciYetki", con);

DataTable dt = new DataTable();

da.Fill(dt);

s["d2"] = dt;

}

void Doldur3(object durum)

{

HttpSessionState s = (HttpSessionState)durum;

SqlConnection con = new SqlConnection("server=.\SQlExpress;database=DryCleaners;User Id=sa;Password=1");

SqlDataAdapter da = new SqlDataAdapter("Select top 10 * from Urunler", con);

DataTable dt = new DataTable();

da.Fill(dt);

s["d3"] = dt;

}

void Doldur4(object durum)

{

HttpSessionState s = (HttpSessionState)durum;

SqlConnection con = new SqlConnection("server=.\SQlExpress;database=DryCleaners;User Id=sa;Password=1");

SqlDataAdapter da = new SqlDataAdapter("Select * from MusteriTuru_Islem_Fiyat union Select * from MusteriTuru_Islem_Fiyat", con);

DataTable dt = new DataTable();

da.Fill(dt);

s["d4"] = dt;

}

protected void Timer2_Tick(object sender, EventArgs e)

{

if (Session["d2"] != null)

{

GridView2.DataSource = (DataTable)Session["d2"];

GridView2.DataBind();

Timer2.Enabled = false;

Session["d2"] = null;

}

}

protected void Timer3_Tick(object sender, EventArgs e)

{

if (Session["d3"] != null)

{

GridView3.DataSource = (DataTable)Session["d3"];

GridView3.DataBind();

Timer3.Enabled = false;

Session["d3"] = null;

}

}

protected void Timer4_Tick(object sender, EventArgs e)

{

if (Session["d4"] != null)

{

GridView4.DataSource = (DataTable)Session["d4"];

GridView4.DataBind();

Timer4.Enabled = false;

Session["d4"] = null;

}

}

}

Hardware TIM [ Sky_Lab ]

Döküman Arama

Başlık :

Kapat