Uygulamanızın ana thread'ini durdurmadan(kullanıcı ile etkileşimli kalmaya devam edecek şekilde); bir başka senkronizayson nesnesini ya da bir thread'i nasıl beklersiniz ?
Örneğin;
procedure TForm1.Button1Click(Sender : TObject);
var
Thrd : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
procedure
begin
Sleep(10000);
end
);
Thrd.Start;
// Yukarıdaki thread kendi içinde 10 sn bekliyor. Biz de tam bu nokta da yukarıdaki thread'in bitmesini bekleyeceğiz. Ama nasıl ;-)
AnaThreadDonmadanBuradaYukaridakiThreadiBekleyelim;
Memo1.Lines.Add('Thread bitti');
end;
Önemli bir husus olduğu için 100 puan vereceğim beklediğim cevaba. Ancak, kayda değer cevaplara da yine puan vereceğim. Tabii teori değil, kod istiyoruz ;-)
Merhaba.
Aklıma direkt anonim thread nasıl syncronize edilir sorusu geliyor.
Dolayısıyla bir thread'e göre global ama procedure içerisine yerleşik bir boolean değişken koyup bunun true veya false durumuna göre bir While NOT degisken şeklinde bir döngüde Application.ProcessMessages döngüsü gibi geliyor. Sonra da geriye kalan bu değişkeni thread ile senkron etmek.
Şöyle bir şey denedim.
procedure TForm1.Button1Click(Sender : TObject);
Var
xDurum : boolean;
Thrd : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
procedure
begin
Sleep(10000);
TThread.Synchronize ( TThread.CurrentThread,
procedure ()
begin
xDurum := True;
end
);
end
);
Thrd.Start;
while NOT xDurum do
begin
Application.ProcessMessages;
end;
// Yukarıdaki thread kendi içinde 10 sn bekliyor. Biz de tam bu nokta da yukarıdaki thread'in bitmesini bekleyeceğiz. Ama nasıl ;-)
//AnaThreadDonmadanBuradaYukaridakiThreadiBekleyelim;
Memo1.Lines.Add('Thread bitti');
end;
- Her zaman olduğu gibi soru süper üstadım tebrikler.
- Değişken atama için syncronize lazım mı değil mi ? Onu hiç düşünmedim

Bir method'a değer aktarmıyoruz sonuçta. Direkt bu değişkene de eşitleyince de olur bence.

Başlığı okuyanlara anlatıyorum, tercihen sleep kullanmak durumunda olsaydım 10000 milisaniye değil de 10 milisaniye dilimler halinde 1'den 1000'e kadar bir döngü kurar içinde application.processmessages koyardım. Böylece 10 milisaniyelik donmalar beni üzmezdi.

Kendi uyguladığım method ise GetTickCount + 10 saniye ( 10000 milisaniye ) değerini bir değişkene alır, while döngüsünde güncel GetTickCount'un bu değişkendeki değerin üzerine çıktığı anı yine application.processmessages ile beklemek şeklinde oluyor.
(30-04-2018, Saat: 09:25)mrmarman Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba.
Aklıma direkt anonim thread nasıl syncronize edilir sorusu geliyor.
Dolayısıyla bir thread'e göre global ama procedure içerisine yerleşik bir boolean değişken koyup bunun true veya false durumuna göre bir While NOT degisken şeklinde bir döngüde Application.ProcessMessages döngüsü gibi geliyor. Sonra da geriye kalan bu değişkeni thread ile senkron etmek.
Şöyle bir şey denedim.
procedure TForm1.Button1Click(Sender : TObject);
Var
xDurum : boolean;
Thrd : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
procedure
begin
Sleep(10000);
TThread.Synchronize ( TThread.CurrentThread,
procedure ()
begin
xDurum := True;
end
);
end
);
Thrd.Start;
while NOT xDurum do
begin
Application.ProcessMessages;
end;
// Yukarıdaki thread kendi içinde 10 sn bekliyor. Biz de tam bu nokta da yukarıdaki thread'in bitmesini bekleyeceğiz. Ama nasıl ;-)
//AnaThreadDonmadanBuradaYukaridakiThreadiBekleyelim;
Memo1.Lines.Add('Thread bitti');
end;
- Her zaman olduğu gibi soru süper üstadım tebrikler.
- Değişken atama için syncronize lazım mı değil mi ? Onu hiç düşünmedim
Bir method'a değer aktarmıyoruz sonuçta. Direkt bu değişkene de eşitleyince de olur bence.
Başlığı okuyanlara anlatıyorum, tercihen sleep kullanmak durumunda olsaydım 10000 milisaniye değil de 10 milisaniye dilimler halinde 1'den 1000'e kadar bir döngü kurar içinde application.processmessages koyardım. Böylece 10 milisaniyelik donmalar beni üzmezdi.
Kendi uyguladığım method ise GetTickCount + 10 saniye ( 10000 milisaniye ) değerini bir değişkene alır, while döngüsünde güncel GetTickCount'un bu değişkendeki değerin üzerine çıktığı anı yine application.processmessages ile beklemek şeklinde oluyor.
Ellerinize sağlık üstadım. İlginize teşekkür ederim. Sizin kullanımınızda bir sıkıntı olmaz. Çünkü değişken lokal ve o değişkene erişen başka bir thread yok. Application.ProcessMessages önerisi geleceğini biliyordum.
Şimdi sizden ricam, uygulamanızın kullandığı CPU yüzdesine bakın ;-)
Asıl amacımız CPU'yu yormayacak bir çözüm. İhtiyaç hasıl olur ise, ipucu verebilirim; böylece o istikamette yürüyebiliriz.
(30-04-2018, Saat: 09:44)mrmarman Adlı Kullanıcıdan Alıntı: [ -> ]Anladım. Teşekkürler.
Oltaya düştük demek 
Estağfirullah üstadım. Sizinki çok doğal bir yanıt ve makul bir yanıt aynı zamanda. Ancak, çok çok daha iyi ve efektif olanı mevcut.
Selam @
Tuğrul HELVACI Hocam
Ben @
mrmarman hocamın koduna sadece TThread.Sleep(10); fonsiyonunu ekledim. ondan örnek alıp. (Tırtıklayıp )
CPU nerdeyse %1 bile yer işgal etmiyor.
Çok fazla Thread kullanan biri olarak doğru cevabı sabırsızlıkla bekliyorum.
while NOT xDurum do
begin
TThread.Sleep(10);
Application.ProcessMessages;
end;
Sleep(10) satırını ilgili döngünün içinde kullanmak; işletim sistemine uygulamanızın main thread'ini 10 milisaniye boyunca durdur demektir. Ancak realite'de bu süre 10 milisaniyeden çok daha uzun olacaktır. Çünkü thread'iniz işletim sisteminin scheduler'ı tarafından durdurulmuş ve çalıştırılma sırası diğer thread'lere geçmiştir. Round Robin, priority round robin yapısında thread'inize boosting bile uygulansa; threadinize geri dönüş süresi 10 milisaniyeden uzun olacaktır.
Dolayısı ile istediğimiz şey Sleep değil. Bu arada yeri gelmişken Sleep(0)'dan bahsetmeden olmaz. Sleep(0) özel bir anlam ifade eder. Sleep(0) işletim sistemine; "eğer çalıştırılmak için bekleyen başka thread'ler var ise buyur onları çalıştır kardeşim, benim daha fazla çalışma zamanına ihtiyacım yok. Ama bekleyen thread yoksa, ben çalışmaya devam ederim" demektir.
Sleep(0) =
SwitchToThread.
Benim sizlerden araştırmanızı istediğim API'ler aşağıdakiler olacaktır. Tabii öğrenmek isteyene;
Cevaplarınızı bekliyorum

procedure TForm1.Button1Click(Sender : TObject);
Var
Thrd : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
procedure
begin
Sleep(10000);
TThread.Synchronize ( TThread.CurrentThread,
procedure ()
begin
memo1.lines.add('İşlem bitti');
end
);
end
);
Thrd.Start;
Böyle çok güzel çalışıyor hocam, bence bozmayalım

(30-04-2018, Saat: 11:51)esistem Adlı Kullanıcıdan Alıntı: [ -> ]
procedure TForm1.Button1Click(Sender : TObject);
Var
Thrd : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
procedure
begin
Sleep(10000);
TThread.Synchronize ( TThread.CurrentThread,
procedure ()
begin
memo1.lines.add('İşlem bitti');
end
);
end
);
Thrd.Start;
Böyle çok güzel çalışıyor hocam, bence bozmayalım 
Herhangi bir senkronizasyon nesnesini beklemeye ihtiyacınız olduğunda ve ana thread'iniz kilitlendiğinde ya da çok fazla CPU kullandığında; ilgili konumuza yeniden bekleriz o halde sizi sevgili üstadım

Benim cevap hakkım yok dimi
