Delphi Can
Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - Baskı Önizleme

+- Delphi Can (http://www.delphican.com)
+-- Forum: Delphi (http://www.delphican.com/forumdisplay.php?fid=3)
+--- Forum: Mobil Platform - FireMonkey (FMX) (http://www.delphican.com/forumdisplay.php?fid=7)
+--- Konu Başlığı: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. (/showthread.php?tid=1393)

Sayfalar: 1 2


Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - pro_imaj - 05-10-2017

Merhaba Arkadaşlar;

Mobil tarafta zaman alan kısımlarda AniIndicator çalıştırılmaya çalışıldığında, işlem uzun sürse bile AniIndicator  hiç ekrana gelmeden direk işlem gerçekleşiyor. Hem işlemin devam etmesi hemde AniIndicator çalışması için Thread haricinde kullanabileceğimiz basit bir yöntem var mıdır.

Kısaca Thread kullanmadan AniIndicator nasıl düzgün çalıştırılabilir.

*Konuyla ilgili olarak; IdThreadComponent tam olarak ne için kullanılıyor, bununla yapsam ne gibi sakıncaları olur. (Bu konuda birkaç test yaptım sonuçlar olumu fakat component'in amacını bilmiyorum.)

Teşekkürler.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - Tuğrul HELVACI - 05-10-2017

(05-10-2017, Saat: 11:35)pro_imaj Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Merhaba Arkadaşlar;

Mobil tarafta zaman alan kısımlarda AniIndicator çalıştırılmaya çalışıldığında, işlem uzun sürse bile AniIndicator  hiç ekrana gelmeden direk işlem gerçekleşiyor. Hem işlemin devam etmesi hemde AniIndicator çalışması için Thread haricinde kullanabileceğimiz basit bir yöntem var mıdır.

Kısaca Thread kullanmadan AniIndicator nasıl düzgün çalıştırılabilir.

*Konuyla ilgili olarak; IdThreadComponent tam olarak ne için kullanılıyor, bununla yapsam ne gibi sakıncaları olur. (Bu konuda birkaç test yaptım sonuçlar olumu fakat component'in amacını bilmiyorum.)

Teşekkürler.

Uygulamanın ana thread'i meşgul iken, görsel nesnelerin güncellenmesi için gönderilen mesajlar, mesaj kuyruğundan alınıp işlenemez. Dolayısı ile görsel nesneler de güncellenemezler. Amiyane tabir ile "herşey yağ gibi akıp gitsin" istiyor iseniz, ya uzun süren işleminizi bir başka thread içinde çağıracaksınız(ana thread'i bloke etmeyeceksiniz) ya da imkanınız var ise uzun süren işlem adımlarının arasına Application.ProcessMessages satırını serpiştireceksiniz. Bu sayede uygulamanın ana thread'inin mesaj kuyruğuna gönderilen mesajlar kısmen alınıp işlenebilir olacak ve görsel nesneleriniz kendilerini güncelleyebilme imkanı bulacaklardır.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - pro_imaj - 05-10-2017

(05-10-2017, Saat: 11:55)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
(05-10-2017, Saat: 11:35)pro_imaj Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Merhaba Arkadaşlar;

Mobil tarafta zaman alan kısımlarda AniIndicator çalıştırılmaya çalışıldığında, işlem uzun sürse bile AniIndicator  hiç ekrana gelmeden direk işlem gerçekleşiyor. Hem işlemin devam etmesi hemde AniIndicator çalışması için Thread haricinde kullanabileceğimiz basit bir yöntem var mıdır.

Kısaca Thread kullanmadan AniIndicator nasıl düzgün çalıştırılabilir.

*Konuyla ilgili olarak; IdThreadComponent tam olarak ne için kullanılıyor, bununla yapsam ne gibi sakıncaları olur. (Bu konuda birkaç test yaptım sonuçlar olumu fakat component'in amacını bilmiyorum.)

Teşekkürler.

Uygulamanın ana thread'i meşgul iken, görsel nesnelerin güncellenmesi için gönderilen mesajlar, mesaj kuyruğundan alınıp işlenemez. Dolayısı ile görsel nesneler de güncellenemezler. Amiyane tabir ile "herşey yağ gibi akıp gitsin" istiyor iseniz, ya uzun süren işleminizi bir başka thread içinde çağıracaksınız(ana thread'i bloke etmeyeceksiniz) ya da imkanınız var ise uzun süren işlem adımlarının arasına Application.ProcessMessages satırını serpiştireceksiniz. Bu sayede uygulamanın ana thread'inin mesaj kuyruğuna gönderilen mesajlar kısmen alınıp işlenebilir olacak ve görsel nesneleriniz kendilerini güncelleyebilme imkanı bulacaklardır.

Cevap için teşekkür ederim Tuğrul Hocam;
Application.ProcessMessages bazı işlemlerde kullanıyordum fakat burada SQL kodu çalıştığı için işimi görmüyor. Thread konusundada IdThreadComponent nesnesini onRun olayını kullanarak çalışan sql kodunu olduğu procedure'yi çağırıyorum tek sorun çalışan sql kodunun verileri ekrana bağlı olan ListView'e gelmiyor. (Aynı sql kodunun olduğu procdure'yi normal şekilde çağırdığımda veriler ListView'e geliyor.)

Bunun nedeni ne olabilir.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - Tuğrul HELVACI - 05-10-2017

(05-10-2017, Saat: 13:27)pro_imaj Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
(05-10-2017, Saat: 11:55)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Uygulamanın ana thread'i meşgul iken, görsel nesnelerin güncellenmesi için gönderilen mesajlar, mesaj kuyruğundan alınıp işlenemez. Dolayısı ile görsel nesneler de güncellenemezler. Amiyane tabir ile "herşey yağ gibi akıp gitsin" istiyor iseniz, ya uzun süren işleminizi bir başka thread içinde çağıracaksınız(ana thread'i bloke etmeyeceksiniz) ya da imkanınız var ise uzun süren işlem adımlarının arasına Application.ProcessMessages satırını serpiştireceksiniz. Bu sayede uygulamanın ana thread'inin mesaj kuyruğuna gönderilen mesajlar kısmen alınıp işlenebilir olacak ve görsel nesneleriniz kendilerini güncelleyebilme imkanı bulacaklardır.

Cevap için teşekkür ederim Tuğrul Hocam;
Application.ProcessMessages bazı işlemlerde kullanıyordum fakat burada SQL kodu çalıştığı için işimi görmüyor. Thread konusundada IdThreadComponent nesnesini onRun olayını kullanarak çalışan sql kodunu olduğu procedure'yi çağırıyorum tek sorun çalışan sql kodunun verileri ekrana bağlı olan ListView'e gelmiyor. (Aynı sql kodunun olduğu procdure'yi normal şekilde çağırdığımda veriler ListView'e geliyor.)

Bunun nedeni ne olabilir.

İlgili component muhtemelen OnRun olayına yazdığınız kodu bir thread içinde çalıştırıyordur. Main thread haricindeki thread'ler içinde iken görsel nesnelere erişmeye çalışmak, onları güncellemek; her türlü hata olasılığına açıktır. Sözün özü, ListView içine ekleme yaptığınız bölümü, TThread.Synchronize ile ya da TThread.Queue ile senkronize etmelisiniz.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - pro_imaj - 05-10-2017

Merhaba;

Bilgilendirme için tekrar teşekkür ederim.
 
Sorunumun kaynağını buldum! Thread nesnesinin aktiflik durumunu false yapsak bile Thread çalışmaya devam ediyormuş.

Çözüm
onRun olayında Terminate diyerek çözdüm.
Sender.Terminate;


*IdThreadComponent yeni keşfetmiş birisi olarak Thread işlemlerini artık bu yolla çok kolay ve hızlı bir şekilde yapılabileceğini bu vesileyle keşfetmiş oldum, herkese tavsiye ederim.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - Fesih ARSLAN - 05-10-2017

Merhaba,
Malum bu aralar formumuzda alternatif çözümler revaçta, bu vesile ile nesne kullanmadan, örnek bir kod paylaşımı yapayım.
TThread.CreateAnonymousThread(
 procedure ()
 begin
   TThread.Synchronize (nil,
     procedure ()
     begin
       AniIndicator1.Visible := True;
       AniIndicator1.Enabled := True;
     end
   );
   try
     //işlemleriniz;
   finally
   //  TThread.Synchronize (nil,
   //    procedure ()
   //    begin
         AniIndicator1.Enabled := False;
         AniIndicator1.Visible := False;
   //    end);
   end;
 end
).Start;

finally bölümündeki kodları opsiyonel yaptım. Smile 
Sebebi ise Android uygulamalarda AnonymousThread işlemi tamamlandıktan (örneğin, ListView dolduruluyor) hemen sonra AniIndicator'ün gizlenmesi, az da olsa zaman alıyor (1-2 sn.). Finally bölümündeki  Synchronize'ı kapatınca, thread bitimine müteakip AniIndicator gizleniyor.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - pro_imaj - 06-10-2017

Fesih hocam sizin yöntemde çok şık.

Sizin yöntem ve benim uyguladığım yöntemle; Windows ve Android'te sorunsuz çalışıyorken ios tarafında  çalışmıyor.

1-İlgili tab'ı aktif etme işlemini Thread'içinde kullanırsam işlemin başladığı tuşa ikinci kez bastığımda tabRapor aktif oluyor ve verilerde geliyor.
2-İlgili tab'ı aktif etme işlemini Thread' dışında ilgili butonda kullanırsam tab aktif oluyor fakat bu seferde ListView boş gözüküyor ekranda herhangi bir yere dokunduğumda veriler geliyor
Kod:
TabControl1.ActiveTab := tabRapor;


Delphi : 10.2.1
ios : 10.0.2


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - Tuğrul HELVACI - 06-10-2017

(06-10-2017, Saat: 00:25)pro_imaj Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Fesih hocam sizin yöntemde çok şık.

Sizin yöntem ve benim uyguladığım yöntemle; Windows ve Android'te sorunsuz çalışıyorken ios tarafında  çalışmıyor.

1-İlgili tab'ı aktif etme işlemini Thread'içinde kullanırsam işlemin başladığı tuşa ikinci kez bastığımda tabRapor aktif oluyor ve verilerde geliyor.
2-İlgili tab'ı aktif etme işlemini Thread' dışında ilgili butonda kullanırsam tab aktif oluyor fakat bu seferde ListView boş gözüküyor ekranda herhangi bir yere dokunduğumda veriler geliyor
Kod:
TabControl1.ActiveTab := tabRapor;


Delphi : 10.2.1
ios : 10.0.2

En iyisi yazdığınız kodu görmemiz sanıyorum. Aksi taktirde afaki konuşmaya devam edeceğiz.


Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - pro_imaj - 06-10-2017

Haklısınız kodları yazmamışım.  Blush

procedure TfrmAna.ListBoxItem2Click(Sender: TObject);
begin
 RaporNo := 1;

 frmDM.IdThreadGenel.Active := True;
 frmAna.TabControl1.ActiveTab := frmAna.tabRapor;
//Thread aktif olunca Run, AfterRun ve Before Run işlemin durumuna göre aktif oluyor.
end;


procedure TfrmDM.IdThreadGenelAfterRun(Sender: TIdThreadComponent);
begin
 frmAna.AniIndicator1.Visible := False;
 frmAna.AniIndicator1.Enabled := False;
 frmAna.AniIndicator1.SendToBack;
end;

procedure TfrmDM.IdThreadGenelBeforeRun(Sender: TIdThreadComponent);
begin
 frmAna.AniIndicator1.Visible := True;
 frmAna.AniIndicator1.Enabled := True;
 frmAna.AniIndicator1.BringToFront;
end;

procedure TfrmDM.IdThreadGenelRun(Sender: TIdThreadComponent);
begin
 try
    TThread.Sleep(300);
   frmAna.RaporBaslik()
 except

 end;
 Sender.Terminate;
end;

procedure TfrmAna.RaporBaslik();
begin
 DatabaseBaglan();

 case RaporNo of
   1:
     begin
       frmDM.QBaslik.Close;
       frmDM.QBaslik.SQL.Clear;
       frmDM.QBaslik.SQL.Text := 'exec dbo.S01A';
       frmDM.QBaslik.Open;
     end;
   2:
     begin
       frmDM.QBaslik.Close;
       frmDM.QBaslik.SQL.Clear;
       frmDM.QBaslik.SQL.Text := 'exec dbo.S02A';
       frmDM.QBaslik.Open;
     end;

 end;
end;

procedure TfrmAna.DatabaseBaglan();
begin
 try
   if frmDM.conServer.Connected = False then
     frmDM.conServer.Connected := True;
 Except
   ShowMessage('Check Your Internet Connection');
   exit;
 end;
end;



Cvp: Thread kullanmadan veya IdThreadComponent ile AniIndicator kullanımı hk. - Tuğrul HELVACI - 06-10-2017

İlgili component'i hiç kullanmadım, kodlarını da incelemedim ama; mantıken BeforeRun ve AfterRun olaylarının main thread içinden çağrılıyor olması gerekir. Bu durumda, ilgili event'lerde görsel nesnelere erişimde bir sıkıntı yaşamazsınız. Ancak bir thread içinde veritabanı işlemleri yapıyorsanız, kullandığınız connection'ın thread'e has olması gerekir. Main thread'in kullandığı connection'ı bir başka thread içinde kullanmak sağlıklı sonuçlar vermez. Örneğin, uygulamanızın ana thread'i ilgili connection üzerinden veri çekiyor ya da veri gönderiyor olabilir, bir diğer thread'de aynı connection üzerinden veri göndermeye ya da almaya kalkarsa sonuçlar arzu ettiğiniz gibi olmayacaktır Wink 

 Ayrıca ListView'i LiveBindings ile dolduruyorsanız, bu durumda siz bir thread içinden görsel nesnelere erişimde bulunuyorsunuz demektir -ki bu hiç de tavsiye edilen bir durum değildir. Peki ne yapabilirsiniz ? Tasarım anındaki livebindings bağlantılarınızı iptal edip, thread'in bitmesine müteakip yeniden kurarsanız bir sıkıntı yaşamamalısınız.

Thread kullanmak kolaydır ama dikkat edilmesi gereken ince nüanslar vardır. Wink