Makale Özeti

Bu yazımızda asenkron Web Servisi çagırma teknikleri uzerinde duracağız.Asenkronize XML Web Servisi yaparak, XML Web Servisinden sonuç dönmesinin beklerken de çağrımı kullanmaya devam edebilirsiniz.

Makale

Merhabalar,

 

Bu yazımızda asenkron Web Servisi çagırma teknikleri uzerinde duracağız.Asenkronize XML Web Servisi yaparak, XML Web Servisinden sonuç dönmesinin beklerken de çağrımı kullanmaya devam edebilirsiniz. Bu, kullanıcıların XML Web Servisine giriş onaylanırken de uygulamayı kitlemeden işlemlerine devam edebilecekleri anlamına gelir. Bu daha iyi bir dizayn örneğidir ve multithread desteğini kullanarak, Smart Device uygulamalarında thread kullanımı daha etkilidir. Asenkronize çağrılar yaparken, çağrı, kullanıcı arayüzünde çalışan threadden farklı bir thread kullanır. XML Web Servisi uygulaması ne özel bir asenkronize çağrı konfigürasyonuna nede uygulamayı senkronize yada asenkronize çağırdığınıza ait bir bilgiye ihtiyaç duyar. Proxy class’ında ki her senkronize method için uygun bir “Begin”, “End” methodu vardır. Mesela, XML Web Servisimizin metodunun adı “GetItems” ise, asenkronize methodlarımızın adları BeginGetItems ve EndGetItems olur.

 

XML Web Servisi asenkronize çağırmak iki basamaklı bir operasyondur. Öncelikle, Web Methodu başlatmak için Begin methodunu çağırılır. İkinci olarak, XML Web Servisini tamamlamak ve sonucu almak için End methodu çağırılır.

 

Begin methodu, System.IAsyncResult arayüzünü oluşturan System.Web.Services.Protocol.WebClientAsyncResult objesini döndürür. Bu obje, sonucu beklenen asenkron çağrının durum bilgisini verir. Bu objeyi End methoduna göndererek, özellikle bir çok asenkronize çağrı yapıldığında proxy class’ın tamamlanması istenen çağrıyı tanımlaması sağlanır.

 

 

Asenkron XML Web Servis çağrılarının sonuçlandığını anlamanın çeşitli yolları vardır :

 

  • Begin methoduna geriçağrı (callback) gönderilir ve geriçağrı XML Web Servisinin çağrısı tamamlandığında çalışır.
  • Uygulama, IAsyncResult.AsyncHandle objesinin WaitHandle methodlarını kullanarak beklemeye zorlanır. WaitHandle class’ının methodları kullanılırken, kullanıcı XML Web Servisinden dönen sonuçlar gelene kadar bekleyecektir.
  • Ana thread’inizdeki IAsyncResult.IsCompleted özelliğinin değerini True dönene kadar toplayın. True döndüğünde ise XML Web Servisinden sonucu almak için End methodunu çağırın.
  • Asenkron XML Web servisi çağrının tamamlandığınıgösteren diğer yöntemleri kullanmadan direk End methodunu çağırın. Bu method, işlemi asenkron çağrı tamamlanana kadar durduracaktır.

 

 

En Etkili yöntem begin methoduna geriçağrı (callback) gönderilmesidir ki, geriçağrı methodları sonucu beklerken threadleri bloke etmezler. XML Web Servisi sonucu döndüğünde de geriçağrı thread’i yeni bir threadde çalışacaktır. Daha sonra geriçağrının içinde end methodunu çağırabilirsiniz.

 

Aşağıdaki kod, asenkron XML Web Servisi çağrısı yaratmayı gösteriyor; kod, BeginGetItems ı çağırıyor:

 

BeginGetItems (System.AsyncCallBack callback, object, asyncState);

 

BeginGetItems iki parametre alır. İlki, temelinde ServiseCallback’in adresiyle yaratılan AsyncCallback objesi. İkincisi ise herhangi bir objeye gönderilebilen, XML Web Servisinin yanıtını kullanmada yol göstericek parametre tipindeki objedir. Bu objeye AsyncState özelliğinin IAsyncResult parametresiyle ulaşabilirsiniz. Aşağıdaki örnekte, bu şekilde proxy objesine geçirilen obje XML Web Servisidir ki geriçağrı çalıştırıldığında, ServiceCallback methodunda gösterildiği gibi EndGetItems’a çağrı yapılabilecek.

 

private void button2_Click(object sender, System.EventArgs e)
{
    // Async butonunu disable et ve ListView’ı verilerden temizle
    // XML Web service proxy classı yarat
    BookCatalog.Service1 ws = new BookCatalog.Service1();
    // geriçağrıya referans yarat
    AsyncCallback cb = new AsyncCallback(ServiceCallback);
    // Begin methodunu çağır, AsyncState objesi olarak geriçağrıya aktar 
    ws.BeginGetItems(cb,ws);
}
 
private void ServiceCallback(IAsyncResult ar)
{
    // AsyncState objesini proxy objesine ata
    BookCatalog.Service1 ws = (BookCatalog.Service1)ar.AsyncState;
    // End methodunu çağır ve sonucu DataSet e ata
    DataSet ds = ws.EndGetItems(ar);
 
    // DataSet te dön ve her satırın Title_ID ve Title 
    // alanlarını ListView e ekle
    foreach(DataRow drBook in ds.Tables[0].Rows) {
        // ListView a eklemek için yeni bir ListViewItem oluştur
        ListViewItem book = new ListViewItem();
        // Title_ID alanını Text özelliğine ata
        book.Text = drBook["Title_ID"].ToString();
        // Title alanını ilk SubItem a ata
        book.SubItem[0].Text = drBook["Title"].ToString();
        // Kitap ListViewItem ını ListView
        listView1.Items.Add(book);
    }
}

 

Asenkron XML Web Servisi çağrısı yapmak, senkron çağrı yapmaktan biraz daha fazla koda ihtiyaç duyar. Ama sonuçta, daha interaktive bir uygulama kesinlikle uğraşa değer.

 

Bir uyarı: Asenkron XML Web Servisi çağrımı yaparken multithread programlama kullanın.

 

Eğer asenkron XML Web Servisi çağırımı yaparken multithread teknikleri kullanmazsanız, iki veya daha fazla thread aynı anda aynı veriye ulaşmaya çalışırken sorunlarla karşılacaksınız. Aşağıda gösterilen böyle bir teknik, C# da müşterek kullanılan bir objeye tek girişi elde etmek için hazırlanan kilit(lock) mekanizmasını içeriyor ki diğer thread’lerin girişi kabul edilmesin.

 

private void ServiceCallback(IAsyncResult ar)
    // AsyncState objesini proxy objesine ata
    BookCatalog.Service1 ws = (BookCatalog.Service1)ar.AsyncState;
    // // End methodunu çağır ve sonucu DataSet e ata
    DataSet ds = ws.EndGetItems(ar);    
    // Diğer thread lerin girişini engellemek için ListView da lock kullan
    lock(this.listView1)
    {        
    // DataSet te dön ve her satırın Title_ID ve Title 
    // alanlarını ListView e ekle
        foreach(DataRow drBook in ds.Tables[0].Rows) {
            // ListView a eklemek için yeni bir ListViewItem oluştur
            ListViewItem book = new ListViewItem();
            // Title_ID alanını Text özelliğine ata
            book.Text = drBook["Title_ID"].ToString();
            // Title alanını ilk SubItem a ata
            book.SubItem[0].Text = drBook["Title"].ToString();
            // Kitap ListViewItem ını ListView a ekle
            listView1.Items.Add(book);
        }
    }
}

 

Uygulamanızı thread-safe  yapmak için Monitor class’ı ve Control.Invoke gibi diğer teknikleri de araştırmalısınız. Multithread programlamayla ilgili daha fazla bilgiyi MSDN Library den bulabilirsiniz.

 

Hepinize kolay gelsin.

 

HAKAN ULAGAN

hakan.ulagan@netron.com.tr