Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Thread içerinde for ve sleep işleminde uygulama kırılmasını önleme
#1
Merhaba,

Label içindeki sayıyı görsellik olması açısında aşağıdaki thread ile 0 sayısından başlatarak ilgili sayıya kadar göstermek istiyorum.

Windows tarafında aşağıdaki şekilde istediğim oluyorken mobil tarafta uygulama kırılıyor (kapanıyor)
Bu konuda nasıl bir yöntem izlemek gerekir.

 
 TThread.CreateAnonymousThread(
   procedure()
   var
     a: integer;
   begin
     TThread.Synchronize(TThread.CurrentThread,
       procedure()

       begin

       end);
     try
       for a := 0 to StrToInt(lblBekleyen.Text) do
       begin
         Sleep(1);
         lblBekleyen.Text := a.ToString;
       end;
     finally

     end;
   end).Start;
Cevapla
#2
(03-04-2020, Saat: 14:37)pro_imaj Adlı Kullanıcıdan Alıntı: Merhaba,

Label içindeki sayıyı görsellik olması açısında aşağıdaki thread ile 0 sayısından başlatarak ilgili sayıya kadar göstermek istiyorum.

Windows tarafında aşağıdaki şekilde istediğim oluyorken mobil tarafta uygulama kırılıyor (kapanıyor)
Bu konuda nasıl bir yöntem izlemek gerekir.

 
 TThread.CreateAnonymousThread(
   procedure()
   var
     a: integer;
   begin
     TThread.Synchronize(TThread.CurrentThread,
       procedure()

       begin

       end);
     try
       for a := 0 to StrToInt(lblBekleyen.Text) do
       begin
         Sleep(1);
         lblBekleyen.Text := a.ToString;
       end;
     finally

     end;
   end).Start;

 
procedure TForm1.Button1Click(Sender: TObject)
var
    a: integer;
begin
TThread.CreateAnonymousThread(
   procedure()
  begin
      for a := 0 to StrToInt(lblBekleyen.Text) do
      begin
        Sleep(1);
    
     TThread.Synchronize(TThread.CurrentThread,
      procedure()
      begin
         lblBekleyen.Text := a.ToString;
      end);

      end;
  end).Start;

Test etmedim. Çalışacak mı diye kontrol eder misiniz?
A değişkenini ana prosedür/fonksiyona tanımlama yapmanız daha uygun olacaktır.
kisisel_logo_dark.png
WWW
Cevapla
#3
Şuna benzer bir yapı kullanabilirsiniz;

https://www.delphican.com/showthread.php...4#pid35474
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#4
@pro_imaj ; kodunuzu yanlış okumadıysam lblBekleyen.Text'i Synchronize'nin dışında güncelliyorsunuz!
There's no place like 127.0.0.1
WWW
Cevapla
#5
Merhaba,
Thread içerisinden VCL bileşen özelliklerini Synchronize veya Queue ile set edebilirsiniz.
Kodunuzu aşağıdaki gibi değiştirirseniz, sorun muhtemelen çözülecektir.
  TThread.CreateAnonymousThread(
   procedure()
   var
     a, say: integer;
   begin
     say := lblBekleyen.Text.ToInteger;
     for a := 0 to say do
     begin
       TThread.Sleep(100);
       TThread.Queue(TThread.CurrentThread,
         procedure()
         begin
           lblBekleyen.Text := a.ToString;
         end);
     end;
   end).Start;
Cevapla
#6
(03-04-2020, Saat: 15:16)Halil Han Badem Adlı Kullanıcıdan Alıntı:
(03-04-2020, Saat: 14:37)pro_imaj Adlı Kullanıcıdan Alıntı: Merhaba,

Label içindeki sayıyı görsellik olması açısında aşağıdaki thread ile 0 sayısından başlatarak ilgili sayıya kadar göstermek istiyorum.

Windows tarafında aşağıdaki şekilde istediğim oluyorken mobil tarafta uygulama kırılıyor (kapanıyor)
Bu konuda nasıl bir yöntem izlemek gerekir.

 
 TThread.CreateAnonymousThread(
   procedure()
   var
     a: integer;
   begin
     TThread.Synchronize(TThread.CurrentThread,
       procedure()

       begin

       end);
     try
       for a := 0 to StrToInt(lblBekleyen.Text) do
       begin
         Sleep(1);
         lblBekleyen.Text := a.ToString;
       end;
     finally

     end;
   end).Start;

 
procedure TForm1.Button1Click(Sender: TObject)
var
    a: integer;
begin
TThread.CreateAnonymousThread(
   procedure()
  begin
      for a := 0 to StrToInt(lblBekleyen.Text) do
      begin
        Sleep(1);
    
     TThread.Synchronize(TThread.CurrentThread,
      procedure()
      begin
         lblBekleyen.Text := a.ToString;
      end);

      end;
  end).Start;

Test etmedim. Çalışacak mı diye kontrol eder misiniz?
A değişkenini ana prosedür/fonksiyona tanımlama yapmanız daha uygun olacaktır.

Cevap için teşekkürler.
Böyle bir kullanım desteklenmiyor.

(03-04-2020, Saat: 15:20)uparlayan Adlı Kullanıcıdan Alıntı: Şuna benzer bir yapı kullanabilirsiniz;

https://www.delphican.com/showthread.php...4#pid35474

Cevap için teşekkürler.
Sizin kullanımı inceliyorum.

(03-04-2020, Saat: 16:12)SimaWB Adlı Kullanıcıdan Alıntı: @pro_imaj ; kodunuzu yanlış okumadıysam lblBekleyen.Text'i Synchronize'nin dışında güncelliyorsunuz!

Cevap için teşekkürle.r
Diğer durumda işlem bitmeden sonucu göremiyorum.

(03-04-2020, Saat: 16:23)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: Merhaba,
Thread içerisinden VCL bileşen özelliklerini Synchronize veya Queue ile set edebilirsiniz.
Kodunuzu aşağıdaki gibi değiştirirseniz, sorun muhtemelen çözülecektir.
  TThread.CreateAnonymousThread(
   procedure()
   var
     a, say: integer;
   begin
     say := lblBekleyen.Text.ToInteger;
     for a := 0 to say do
     begin
       TThread.Sleep(100);
       TThread.Queue(TThread.CurrentThread,
         procedure()
         begin
           lblBekleyen.Text := a.ToString;
         end);
     end;
   end).Start;

Cevap için teşekkürler.
Sizin yazdığınız şekilde işlem yaparken, windows tarafında işlem bitmeden program kapatılırsa sonsuz hata mesajına düşüyor, mobilde ayrıca deneyeceğim.

*Farklı farklı uygulamaları deniyorum bu defada hataya düşmese dahi ekrana yansıyan bir şey olmuyor. Ekrana dokunduğumda veya scroll ile hareket ettiğimde label'deki verinin değiştiğini gözlemliyorum.
Cevapla
#7
(03-04-2020, Saat: 16:23)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: Merhaba,
Thread içerisinden VCL bileşen özelliklerini Synchronize veya Queue ile set edebilirsiniz.
Kodunuzu aşağıdaki gibi değiştirirseniz, sorun muhtemelen çözülecektir.
  TThread.CreateAnonymousThread(
   procedure()
   var
     a, say: integer;
   begin
     say := lblBekleyen.Text.ToInteger;
     for a := 0 to say do
     begin
       TThread.Sleep(100);
       TThread.Queue(TThread.CurrentThread,
         procedure()
         begin
           lblBekleyen.Text := a.ToString;
         end);
     end;
   end).Start;

@"Fesih ARSLAN" Bu şekilde hata veya donma olmadı. Fakat ilgili sayıdan fazla yada eksik olabiliyor neden olabilir ki, çok mantıksız geldi.



Aşağıdaki  4 label için ayrı aynı bu thread yazdım.  Label'lerdeki değerler sabit olmasına rağmen ilgili thread çalıştıktan sonraki label'lerdeki ilk değerlerden farklı oluyor -+ Bu çok ilginç geldi, tekrar tekrar kontrol ettim kodlar doğru fakat sonuçlar nasıl böyle olabiliyor. 

Label.Text Değeri - Sonuç Ekranda gözüken = Fark
977 - 969 = 8
355 - 355 = 0
33313 - 33133 = 180
36577 - 36574 =  3

*Her çalıştırmada değişiyor!
*TThread.Sleep(1); olarak kullandım sayı fazla olduğu için.
Cevapla
#8
TThread.Queue metodunun birinci paremetresini nil vererek deneyin.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#9
Ayrıca belirtmek isterim; Android, IOS işletim sistemlerinin iç yapısını Windows'un ki kadar iyi bilmiyorum ama; onlarda da thread scheduler'ın 1 milisaniyede thread schedule edemeyeceğine inanıyorum. Çünkü bu işletim sistemleri real-time işletim sistemleri değiller. Bu nedenle Sleep(1) çağrımınız aslında 1 milisaniyeden çok daha uzun süre bekleyecektir.

Synchronize kısaca; ana thread al bu işi sen işlet, ben de işin bitmesini bekleyeyim demektir. Dolayısı ile Syncronize içinde çağıran thread'i bekleyen kod deadlock'a neden olur. Multi thread programlamanın doğasında paralellik vardır. Tüm işi ana thread'e yaptırmak istiyorsak, yeni thread'ler kullanmanın hiç bir faydası olmaz.

Queue ise kısaca; yazdığınız kodu birinci parametre ile belirtilen thread'in mesaj kuyruğuna ekler.Birinci parametrede belirttiğiniz thread çağıran thread ise (yani TThread.CurrentThread); bu durumda mesaj kuyruğu yok edilirken temizlenir. Bu halde tüm mesajlar işletilmeye fırsat bulunamamış olabilir. İlk parametrenin nil olarak geçilmesi, yapılması istenen işi ana thread'in mesaj kuyruğuna atar. Dolayısı ile her durumda zamanı gelince işletilir.

Not : TThread.Queue ile alakalı bu forumda daha önce açtığım bir konuda bu tehlikeden örnekleri ile bahsetmiştik.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#10
(04-04-2020, Saat: 23:45)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Ayrıca belirtmek isterim; Android, IOS işletim sistemlerinin iç yapısını Windows'un ki kadar iyi bilmiyorum ama; onlarda da thread scheduler'ın 1 milisaniyede thread schedule edemeyeceğine inanıyorum. Çünkü bu işletim sistemleri real-time işletim sistemleri değiller. Bu nedenle Sleep(1) çağrımınız aslında 1 milisaniyeden çok daha uzun süre bekleyecektir.

Synchonine kısaca; ana thread al bu işi sen işlet, ben de işin bitmesini bekleyeyim demektir. Dolayısı ile Syncronize içinde çağıran thread'i bekleyen kod deadlock'a neden olur. Multi thread programlamanın doğasında paralellik vardır. Tüm işi ana thread'e yaptırmak istiyorsak, yeni thread'ler kullanmanın hiç bir faydası olmaz.

Queue ise kısaca; yazdığınız kodu birinci parametre ile belirtilen thread'in mesaj kuyruğuna ekler.Birinci parametrede belirttiğiniz thread çağıran thread ise (yani TThread.CurrentThread); bu durumda mesaj kuyruğu yok edilirken temizlenir. Bu halde tüm mesajlar işletilmeye fırsat bulunamamış olabilir. İlk parametrenin nil olarak geçilmesi, yapılması istenen işi ana thread'in mesaj kuyruğuna atar. Dolayısı ile her durumda zamanı gelince işletilir.

Not : TThread.Queue ile alakalı bu forumda daha önce açtığım bir konuda bu tehlikeden örnekleri ile bahsetmiştik.

Merhaba Tuğrul hocam,

Sorun sadece mobil tarafta değil windows tarafında da oluşuyordu, sayıların +- olmasını sizin yazınızı ve gönderdiğiniz link okumadan önce anlamlandıramıyordum yani nasıl olurda farklı olurdu, hatta başka başka işlemleri yaptığımda bu fark açılıyordu.

Aşağıdaki önerdiğiniz şekilde kullanınca sorun çözülmüş oldu. Yazdığınız linki inceleyince oradaki bir cevap tamda buna işaret ediyormuş.
Alıntı:TThread.Queue metodunun birinci paremetresini nil vererek deneyin.

Teşekkür ederim, aklınıza sağlık.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Google play Uygulama yükleme hatası [Çözüldü] codder71 3 306 23-02-2024, Saat: 22:42
Son Yorum: codder71
  Delphi 12 IOS Simulatorde Uygulama Çalışmıyor elixir84 3 923 07-02-2024, Saat: 17:05
Son Yorum: elixir84
  Delphi 11.3 Andorid 10 ve üzeri uygulama çalışmıyor TuncayDelphi 7 578 07-12-2023, Saat: 01:23
Son Yorum: TuncayDelphi
  ios uygulama Bay_Y 4 383 22-11-2023, Saat: 16:06
Son Yorum: Bay_Y
  Google Play Uygulama Yükleme apachi2006 3 455 20-08-2023, Saat: 23:12
Son Yorum: apachi2006



Konuyu Okuyanlar: 1 Ziyaretçi