Delphi Can

Orjinalini görmek için tıklayınız: Thread içerinde for ve sleep işleminde uygulama kırılmasını önleme
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Sayfalar: 1 2
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;
(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.
Şuna benzer bir yapı kullanabilirsiniz;

https://www.delphican.com/showthread.php...4#pid35474
@pro_imaj ; kodunuzu yanlış okumadıysam lblBekleyen.Text'i Synchronize'nin dışında güncelliyorsunuz!
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;
(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.
(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.
TThread.Queue metodunun birinci paremetresini nil vererek deneyin.
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.
(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.
Sayfalar: 1 2