İyi günler. Fark ettiğim kadarıyla bu arada sırada sorulan bir sorudur. Çok uzun süren bir işlem veya sorgunun bitmesini beklerken proje tepki vermez hale gelir ve bunu kullanıcı dostu bir arayüz haline nasıl getirilmesi gerektiği sık sık sorulur ve genel olarak verilen cevaplarda kanal (thread) kullanarak nasıl aşılacağı tarif edilir. Bu makalede ise bu durumu daha da hazır hale getiren basit bir kütüphane sunulmaktadır. Örnek proje xe5 üzerinde yazıldı ve bir .giff animasyonu oynatmaktadır. Burada asıl olan "
untArkaPlan.pas" dosyası ve burada tanımlı "
TArkaplandaYap" sınıfıdır. Bu sınıf daha eski Delphi sürümlerinde de kullanılabilir. Yöntem aslında basit, işlemi uzun süren olay (TNotifyEvent) veya prosedürün kanal (TThread) kullanılarak arka planda çalıştırılıp bitmesini beklemekten geçiyor. Tabi bu bekleme projemizin VCL ara yüzünü kilitlenmesini engelleyen ara ara (örneğe göre 50 ms. de bir) "
Application.ProcessesMessage" kodunu çalıştırmaktadır. Bu sayede ekranda kullanıcıya sunulan bekleme animasyonu oynatılacak ve bu animasyon da kilitlenmeden asıl işimizin aynı anda geri planda çalışıyor olmasıyla işlem tamamlanacaktır. Burada, arka plana çalışması için gönderilen kodlamalarda bazı noktalara dikkat etmek gerekiyor.
-Arka planda çalışacak kodların, VCL arayüzüne direkt müdahale etmiyor olması gerekmektedir. Malum, VCL'de kanal desteği bulunmamaktadır.
-Eğer DataSet temelli kayıtlar üreten sorgu açılacaksa sorguyu açmadan önce DisableControls ile VCL bağlantısı kesilmeli ve sonunda da tekrar EnableControls ile eski haline alınmalı.
-Arka planda çalıştırılacak işlemlerin içinde diyalog pencereleri olmaması daha sağlıklı olacaktır. Bunun yerine arka planda iş bittikten sonra ana program kanalında diyalog gösterilmeli.
-Bu yöntem kullanılacağı zaman şahsi tavsiyem, ekranı kaplayan bir panel veya form içinde animasyon gösterilmeli ve projede işlem yapılamayacak bir şekle getirilmeli.
İşlemi arka planda çalıştırmak için aşağıdaki gibi kodlarla çağırmak mümkündür. Bu çalıştırılan işlemler hem farklı bir kanaldan yürütülecek hem de bitene kadar bekleniyor olacaktır. İşin püf noktası bu bekleme esnasında programın kilitlenmiyor olmasıdır.
Kod: Tümünü seç
procedure TForm1.Button1Click(Sender: TObject);
begin
...
end;
procedure TForm1.Prosedur;
begin
...
end;
...
...
...
Arkaplanda.Calistir(Button1Click, Button1);
Arkaplanda.Calistir(Prosedur);
Kod: Tümünü seç
raise ASonuc.HataSinifi.Create(ASonuc.HataMesaji);
Ayrıca arka plana atılan bir iş eğer bir istisna (Exception) çıkarmışsa bu bileşen çıkan istisnayı aynı şekilde taklit ederek ana kanala bu istisnayı gönderdiği için hata yakalama konusunda çok farklı yollara gitmeye gerek kalmamaktadır.
Kod: Tümünü seç
try
Arkaplanda.Calistir(Prosedur);
except
on E:Exception do begin
ShowMessage(E.Message);
end;
end;
Ekte XE5 ile yapılmış örnek proje bulunmaktadır. Bu örnekte
ikiSaniyeislemYap ve
SorguAc prosedürleri tanımlıdır. Bu işlemleri hem direkt çalıştıran hem de arka planda çalıştırıp bitme süresini ekranda gösteren butonlar bulunmaktadır. Tabi direkt çalıştırıldıkları zaman animasyon donuyor ama arka planda yürütüldüklerinde ise animasyonda herhangi bir takılma olmuyor. Sorgunun çalışması için ADOConnection nesnesini, Delphi ile gelen örnek "
DBDEMOS.udl" bağlantısını kullanmak gerekmektedir. İyi çalışmalar.