Sunday, March 18, 2018

ProjectBase (PB) ile Asenkron Programlama - Asynchronous Programming with ProjectBase (PB)

PB v4.0.0-beta ile veri tabanı işlemlerinin asenkron olarak yapılabilmesi amacıyla PB içine asenkron mimari eklendi. Asenkron programlama (AP) .NET 4.5 ile ortaya çıktığı için PB'nin kullanılması için minumum .NET 4.5 kullanılması gerekmektedir. AP'de yapılacak yan işler ana işten ayrılarak asenkron bir şekilde halledilmekte ve ana işin bu yan işler sebebiyle meşgul edilmesi engellenebilmektedir. AP bir çok amaçla kullanılabilmekle beraber Forms uygulamalarında UI (User Interface) thread, yani arayüz elemanlarını oluşturan thread, genellikle ana thread olmakla beraber tamamlanması uzun işlerde bu thread uzun süre meşgul edilirse arayüzün cevap vermemesine neden olmaktadır. Ayrıca form yapısında bir arayüz elemanını oluşturan thread'den başka bir thread bu elemana ulaşmaya kalkıştığında ön tanımlı (default) olarak uygulama hata verecektir. AP form uygulamalarında kullanıldığında UI thread sürekli meşgul edilmediği için arayüz sürekli aktif kalacaktır.

AP ayrıca işi birden fazla Thread olarak yaptığı için bu işlerin işlemcilere dağıtımı kolay olmakta ve işlemci sayısına göre hız kazanımı elde edilebilmektedir.

Bu amaçla bu yazıda PB v4.0.0-beta kullanan bir örnek form uygulaması hazırlandı. Burada PB'nin kodlarını Github üzerinde indirip ilgili fonksiyonları Thread.Sleep() fonksiyonu kullanıp geciktirerek AP'nin etkisini daha rahat gözlemleyebilirsiniz. Oluşturulan forms arayüzü aşağıda verilmiştir:



Arayüzde 2 tane GridView, bir button ve bir label kullanılmıştır. DOLDUR tuşuna basıldığında label üzerine yazı yazılmadan önce veri çekme işlemleri başlatılmakta, yazı yazdırılmakta ve veriler GridView'lar içine yüklenmektedir. GridView'lar içine veriler kendi aralarında da eş zamansız yüklendiği için aynı anda yüklenmemektedir. Bu işlemler esnasında arayüz sürekli cevap verir durumda olacaktır.

PB v4.0.0-beta bağlantı yönetimini (Connection Management) eş zamansız (asenkron) yapmamaktadır. Yani bağlantı işlemleri gerçekleştirmek için işlemleri yürüten ana thread kullanılmaktadır. Bu yüzden bağlantı sırasında kısa süreli bir meşguliyet meydana gelebilmektedir. Aşağıda forms uygulamasının kodları verilmiştir:


public class EMPLOYEE
{
    public string FIRST_NAME { get; set; }
    public string LAST_NAME { get; set; }
    public decimal SALARY { get; set; }
    public DateTime? HIRE_DATE { get; set; }

}

private async void BtIslem_Click(object sender, EventArgs e)
{
    string sql = "select * from employees";
    string sql2 = "update employees set first_name = 'VELI YIGIT' where employee_id = 101";

    var db = DatabaseFactory.GetDbObjectAsync(DbSettings.ManuelConnectionManagement);

    var task = db.GetObjectListAsync(sql);
    var task2 = db.ExecuteQueryAsync(sql2);
    var task3 = db.GetObjectListAsync(sql);

    LbBilgi.Text = "Verilerin gelmesini beklememe gerek yok!";

    GwData.DataSource = await task;
    await task2;
    GwData2.DataSource = await task3;

    db.CloseConnection();
}

Tuşun basılma (click) olayında (event) "async" anahtar kelimesi ile asenkron kod içerdiği belirtilmektedir. Asenkron işlemlerin sonuçları "await" anahtar kelimesi kullanılarak beklenmektedir. Bir noktada await kullanıldı ise ana thread beklenen işlem sonuçlanana kadar alt satırları işlememektedir. Yukarıdaki kod bloğunda görüldüğü üzere 2 veri çekme işlemi ve bir güncelleme (update) işlemi asenkron olarak başlatılmaktadır. Label üzerine yazı yazdırıldıktan sonra (bu arada veritabanı işlemleri asenkron olarak devam etmekte), daha sonra sonuçlar beklenerek ilgili arayüz elemanları güncellenmektedir. Bu bekleme işlemi sırasında ana thread bloklanmadığı için arayüz sürekli cevap verir durumda olacaktır.

Burada bir diğer önemli nokta "Manuel Connection Management" modunun kullanılmasıdır. Otomatik yönetimde yan thread bağlantıyı diğerleri işlemler sonuçlanmadan kesebilmekte ve bu durum işlemlerin hatalı sonuçlanmasına neden olabilmektedir. Bu sebeple AP kullanılacak ise Manuel mod veya Transaction mod kullanılması gerekmektedir.

Bütün veritabanı işlemleri sonuçlandıktan sonra bağlandı kesilmektedir.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

 "https://github.com/vyigity/ProjectBase"