Yorumları: 1.313
Konuları: 111
Kayıt Tarihi: 01-07-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 6.983 Üstad
30-04-2018, Saat: 20:25
(Son Düzenleme: 30-04-2018, Saat: 21:48, Düzenleyen: Halil Han BADEM.)
Teşekkürler üstat o zaman başlayayım.
Delphi açılıyor...
Gözlük kutusunda gözlük çıkarıldı ve takıldı...
Klavye hazırlandı...
Ve başlayabilirim.
Şimdi ben normalde yazılım geliştirirken, işin içinden çıkamayınca olayı somutlaştırmaya giderim. Performans kayıpları vermemek için ise elimden gelen hemen hemen tüm metotları denerim. Dediğiniz olaya'da şahsen bu durumda olsam yine somutlaştırırdım. Peki nasıl?
A ve B threadleri olsun.
A Thread = Ana thread.
B Thread = Bizim açtığımız thread.
Şimdi a threadı malum her zaman program ile beraber çalıştığından a threadın içine b threadını sizin örnekteki gibi ekleriz. Sonrası Timer ile kontrol ederim(Ama bunu benim gibi acemi yapar ). Denedim sonuç verdi; ama metot olarak yanlışlık olabilir.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
ThreadBittiMi: String;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
BThread: TThread;
begin
ThreadBittiMi := 'Bitmedi';
BThread := TThread.CreateAnonymousThread( ///Bunun bitmesini bekliyeceğiz...
procedure
begin
try
Sleep(10000);
finally
ThreadBittiMi := 'Bitti';
end;
end
);
BThread.Start;
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if ThreadBittiMi = 'Bitti' then
begin
ShowMessage('Thread sonu');
Timer1.Enabled := False;
end;
end;
end.
NOT: WaitMessage konusunda araştırma yaptım. Delphi ile kaynağa baktım ama WindowsApi arasında olduğu için pek aklım yatmadı. Stackoverflow'da ise adam OmniThread demiş. OmniThread konusunda bilgim yok. Sanırsam bir component ile gelen thread özelliği. Onuda araştırayım belki güzel fikirler çıkar
Saygı ve sevgilerimle..
Yorumları: 1.664
Konuları: 20
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 19.042 Üstad
Beklenen cevap budur veya değildir ama bende CPU kullanımı %5 idi bu çözüm ile %2 seviyesinde.
Timer içerisinde saklı olarak beklenen çözüm yer alıyor olabilir neden olmasın
Saygılarımla
Muharrem ARMAN
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
Sanırım soru yanlış anlaşıldı. Ben sizlerden thread'in bitip/bitmediğini anlamanızı değil; thread'in bitmesini bekler iken ana thread'inizin bloke olmamasını sağlamanızı istemiştim.
Örneğin; aşağıdaki adımları izleyerek bir uygulama yapın:
1- Formunuzun üzerine bir adet TProgressBar koyun ve Style property'sine pbstMarquee değerini atayın.
2- Formunuzun üzerine bir adet TLabel koyun.
3- Formunuzun üzerine bir adet TTimer koyun ve OnTimer olayında formun üzerine koyduğunuz TLabel'ın Caption property'sine sistem saatini yazdırın.
4- Formunuzun uses bölümüne SyncObjs unit'ini ilave edin.
5- Formunuzun private bölümüne Event : TEvent değişken tanımını ekleyin.
6- Formunuzun OnCreate olay yöneticisinde;
Event := TEvent.Create(nil, true, false, '');
7- Formunuzun üzerine bir adet TMemo ve bir adet TButton atın.
8- TButton'unuzun OnClick olay yöneticisine aşağıdaki kodu ekleyin:
Event.ResetEvent;
TThread.CreateAnonymousThread(
procedure
begin
Sleep(10000);
Event.SetEvent;
end
).Start;
// Burada Event için bekleme kodunuz olacak. Ve bu kod uygulamanızı kilitlemeyecek. Progressbar'ın hareket ettiğini
// Timer'ın ilgili zaman değerlerini label'a yazdığını gözlemlemeniz gerek.
Memo1.Lines.Add('Bu satır ancak 10 saniye sonra işletilecek. Ancak bu arada formunuz interaktif olacak. Memoya tıklayıp yazı yazabileceksiniz. Ancak CPU kullanım oranınız da yüksek olmayacak. !');
Sanıyorum şimdi ne demek istediğim daha net anlaşılmış olabilir.
Bu çok önemli bir konudur. Thread kullanan arkadaşlarımızın üzerinde ciddiyetle durmaları gereken bir konudur. Kısaca durumu özetleyecek olur isem;
Bir while döngüsü ile sürekli Application.ProcessMessages çağırmak ideal bir çözüm değildir. Busy waiting yapar ve CPU kullanımınız ciddi oranda artar.
Size araştırmanızı salık verdiğim iki API, CPU kullanımında %0 değerlerini görmenizi ve ana thread'inizin kilitlenmemesini sağlar. Daha fazla ipucu vermek istemiyorum. Araştırmanızı istiyorum.
Öğrenmek isteyen var ise tabii.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 1.313
Konuları: 111
Kayıt Tarihi: 01-07-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 6.983 Üstad
Artık ağlama durumuna geldim... Google dork oluşturdum (description: ("msgwaitformultipleobjects", "delphi")) belki thread ile ilgili kaynak bulurum diye ama yok yani var ama ben anlamıyorum tam Dediğiniz API'ler konusunda alt üst ettim heryeri ama en son aşağıda ki kod çıktı o da çalışmıyor zaten. İzninizle ağlayıp sonra yatacağım
procedure TfrmBeklemeliThread.btnBaslatClick(Sender: TObject);
var
A: Integer;
MSG: TMsg;
begin
Event.ResetEvent;
TThread.CreateAnonymousThread(
Procedure
begin
Sleep(3000);
Event.SetEvent;
end).Start;
// A := MsgWaitForMultipleObjects(1, Event, True, 100, (QS_SENDMESSAGE or QS_POSTMESSAGE));
if GetCurrentThreadId = MainThreadID then
begin
while MsgWaitForMultipleObjects(1, Event, False, INFINITE, QS_SENDMESSAGE) = WAIT_OBJECT_0 + 1 do
begin
MStatus.Lines.Add('Bilgi: Thread durdu!');
PeekMessage(MSG, 0, 0, 0, PM_REMOVE);
end;
end
else
begin
WaitForSingleObject(Event.Handle, INFINITE);
end;
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
(30-04-2018, Saat: 23:53)hyperxman Adlı Kullanıcıdan Alıntı: Artık ağlama durumuna geldim... Google dork oluşturdum (description: ("msgwaitformultipleobjects", "delphi")) belki thread ile ilgili kaynak bulurum diye ama yok yani var ama ben anlamıyorum tam Dediğiniz API'ler konusunda alt üst ettim heryeri ama en son aşağıda ki kod çıktı o da çalışmıyor zaten. İzninizle ağlayıp sonra yatacağım
procedure TfrmBeklemeliThread.btnBaslatClick(Sender: TObject);
var
A: Integer;
MSG: TMsg;
begin
Event.ResetEvent;
TThread.CreateAnonymousThread(
Procedure
begin
Sleep(3000);
Event.SetEvent;
end).Start;
// A := MsgWaitForMultipleObjects(1, Event, True, 100, (QS_SENDMESSAGE or QS_POSTMESSAGE));
if GetCurrentThreadId = MainThreadID then
begin
while MsgWaitForMultipleObjects(1, Event, False, INFINITE, QS_SENDMESSAGE) = WAIT_OBJECT_0 + 1 do
begin
MStatus.Lines.Add('Bilgi: Thread durdu!');
PeekMessage(MSG, 0, 0, 0, PM_REMOVE);
end;
end
else
begin
WaitForSingleObject(Event.Handle, INFINITE);
end;
Acı çekerek öğrenilen bilgi asla zayi olmaz
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 1.313
Konuları: 111
Kayıt Tarihi: 01-07-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 6.983 Üstad
Yorumları: 92
Konuları: 15
Kayıt Tarihi: 28-02-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 313 Acemi
Aşağıdaki fonksiyonun istenilen çözümü içerdiğini düşünüyorum. Umarım çözümü arayanlar için faydalı olur.
kaynak: https://stackoverflow.com/questions/7700...den-window
function ThreadFunc(P: Pointer): Integer; //The worker thread main loop, windows handle initialization and finalization
const
EventCount = 1;
var
EventArray: array[0..EventCount-1] of THandle;
R: Cardinal;
M: TMsg;
begin
Result := 0;
CreateWindowFromThread;
try
EventArray[0] := ExitEvent; // you may add other events if you need - just enlarge the Events array
SetEvent(ThreadReadyEvent);
repeat
R := MsgWaitForMultipleObjects(EventCount, EventArray, False, INFINITE, QS_ALLINPUT);
if R = WAIT_OBJECT_0 + EventCount then
begin
while PeekMessage(M, WindowHandle, 0, 0, PM_REMOVE) do
begin
case M.Message of
WM_QUIT:
Break;
else
begin
TranslateMessage(M);
DispatchMessage(M);
end;
end;
end;
if M.Message = WM_QUIT then
Break;
end else
if R = WAIT_OBJECT_0 then
begin
// we have the ExitEvent signaled - so the thread have to quit
Break;
end else
if R = WAIT_TIMEOUT then
begin
// do nothing, the timeout should not have happened since we have the INFINITE timeout
end else
begin
// some errror happened, or the wait was abandoned with WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
// just exit the thread
Break;
end;
until False;
finally
FreeWindowFromThread;
end;
end;
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
(01-05-2018, Saat: 01:52)canbir Adlı Kullanıcıdan Alıntı: Aşağıdaki fonksiyonun istenilen çözümü içerdiğini düşünüyorum. Umarım çözümü arayanlar için faydalı olur.
kaynak: https://stackoverflow.com/questions/7700...den-window
function ThreadFunc(P: Pointer): Integer; //The worker thread main loop, windows handle initialization and finalization
const
EventCount = 1;
var
EventArray: array[0..EventCount-1] of THandle;
R: Cardinal;
M: TMsg;
begin
Result := 0;
CreateWindowFromThread;
try
EventArray[0] := ExitEvent; // you may add other events if you need - just enlarge the Events array
SetEvent(ThreadReadyEvent);
repeat
R := MsgWaitForMultipleObjects(EventCount, EventArray, False, INFINITE, QS_ALLINPUT);
if R = WAIT_OBJECT_0 + EventCount then
begin
while PeekMessage(M, WindowHandle, 0, 0, PM_REMOVE) do
begin
case M.Message of
WM_QUIT:
Break;
else
begin
TranslateMessage(M);
DispatchMessage(M);
end;
end;
end;
if M.Message = WM_QUIT then
Break;
end else
if R = WAIT_OBJECT_0 then
begin
// we have the ExitEvent signaled - so the thread have to quit
Break;
end else
if R = WAIT_TIMEOUT then
begin
// do nothing, the timeout should not have happened since we have the INFINITE timeout
end else
begin
// some errror happened, or the wait was abandoned with WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
// just exit the thread
Break;
end;
until False;
finally
FreeWindowFromThread;
end;
end;
İlginize teşekkür ederim, ama maksadımız anlamak. Aksi durumda, burada bir çok çözüm görürdünüz. Bir şeyi çözmeye çalışmıyoruz esasen. En azından ben çözmeye çalışmıyorum. Birşeylerin öğrenilmesine vesile olmaya çalışıyorum ve görüyorum ki; ya dikkate alınmıyor bu thread meseleleri ya da insanların öğrenmeye hiç mi hiç niyetleri yok.
Herneyse, paylaştığınız kod bir çok hatalar barındırıyor:
CreateWindowFromThread, ExitEvent, ThreadReadyEvent, WindowHandle, FreeWindowFromThread nedir bunlar ? Elbette ben bunların ne olduğunu tahmin ediyorum ama, çözüm bu şekilde paylaşılmaz.
Paylaşacağınız bir çözüm var ise, paylaşmanızdan önce o çözümü anlamanızı istirham ederim sizlerden.
Bir çok arkadaşım konuyu görmüş, okumuş. Sanırım herkes CPU'yu yormadan nasıl beklenilir biliyor galiba
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 4.224
Konuları: 379
Kayıt Tarihi: 07-07-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 16.975 Üstad
(01-05-2018, Saat: 19:59)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: (01-05-2018, Saat: 01:52)canbir Adlı Kullanıcıdan Alıntı: Aşağıdaki fonksiyonun istenilen çözümü içerdiğini düşünüyorum. Umarım çözümü arayanlar için faydalı olur.
kaynak: https://stackoverflow.com/questions/7700...den-window
function ThreadFunc(P: Pointer): Integer; //The worker thread main loop, windows handle initialization and finalization
const
EventCount = 1;
var
EventArray: array[0..EventCount-1] of THandle;
R: Cardinal;
M: TMsg;
begin
Result := 0;
CreateWindowFromThread;
try
EventArray[0] := ExitEvent; // you may add other events if you need - just enlarge the Events array
SetEvent(ThreadReadyEvent);
repeat
R := MsgWaitForMultipleObjects(EventCount, EventArray, False, INFINITE, QS_ALLINPUT);
if R = WAIT_OBJECT_0 + EventCount then
begin
while PeekMessage(M, WindowHandle, 0, 0, PM_REMOVE) do
begin
case M.Message of
WM_QUIT:
Break;
else
begin
TranslateMessage(M);
DispatchMessage(M);
end;
end;
end;
if M.Message = WM_QUIT then
Break;
end else
if R = WAIT_OBJECT_0 then
begin
// we have the ExitEvent signaled - so the thread have to quit
Break;
end else
if R = WAIT_TIMEOUT then
begin
// do nothing, the timeout should not have happened since we have the INFINITE timeout
end else
begin
// some errror happened, or the wait was abandoned with WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
// just exit the thread
Break;
end;
until False;
finally
FreeWindowFromThread;
end;
end;
İlginize teşekkür ederim, ama maksadımız anlamak. Aksi durumda, burada bir çok çözüm görürdünüz. Bir şeyi çözmeye çalışmıyoruz esasen. En azından ben çözmeye çalışmıyorum. Birşeylerin öğrenilmesine vesile olmaya çalışıyorum ve görüyorum ki; ya dikkate alınmıyor bu thread meseleleri ya da insanların öğrenmeye hiç mi hiç niyetleri yok.
Herneyse, paylaştığınız kod bir çok hatalar barındırıyor:
CreateWindowFromThread, ExitEvent, ThreadReadyEvent, WindowHandle, FreeWindowFromThread nedir bunlar ? Elbette ben bunların ne olduğunu tahmin ediyorum ama, çözüm bu şekilde paylaşılmaz.
Paylaşacağınız bir çözüm var ise, paylaşmanızdan önce o çözümü anlamanızı istirham ederim sizlerden.
Bir çok arkadaşım konuyu görmüş, okumuş. Sanırım herkes CPU'yu yormadan nasıl beklenilir biliyor galiba
Merhaba hocam,
Şahsım adına konuşayım; konuyu okudum, fakat bilmiyorum. Bu amaçla kullandığım bir çok yöntem var. Hiç birinin sizin yöntem gibi olmayacağını bildiğim için asıl yöntemi dört gözle beklemeye devam ediyorum.
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
(01-05-2018, Saat: 20:29)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: (01-05-2018, Saat: 19:59)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: İlginize teşekkür ederim, ama maksadımız anlamak. Aksi durumda, burada bir çok çözüm görürdünüz. Bir şeyi çözmeye çalışmıyoruz esasen. En azından ben çözmeye çalışmıyorum. Birşeylerin öğrenilmesine vesile olmaya çalışıyorum ve görüyorum ki; ya dikkate alınmıyor bu thread meseleleri ya da insanların öğrenmeye hiç mi hiç niyetleri yok.
Herneyse, paylaştığınız kod bir çok hatalar barındırıyor:
CreateWindowFromThread, ExitEvent, ThreadReadyEvent, WindowHandle, FreeWindowFromThread nedir bunlar ? Elbette ben bunların ne olduğunu tahmin ediyorum ama, çözüm bu şekilde paylaşılmaz.
Paylaşacağınız bir çözüm var ise, paylaşmanızdan önce o çözümü anlamanızı istirham ederim sizlerden.
Bir çok arkadaşım konuyu görmüş, okumuş. Sanırım herkes CPU'yu yormadan nasıl beklenilir biliyor galiba
Merhaba hocam,
Şahsım adına konuşayım; konuyu okudum, fakat bilmiyorum. Bu amaçla kullandığım bir çok yöntem var. Hiç birinin sizin yöntem gibi olmayacağını bildiğim için asıl yöntemi dört gözle beklemeye devam ediyorum.
Merhaba üstadım, aslında ben kullanılabilecek API'leri vermiştim. Yapılacak tek şey, o API'lerin ne yaptığını okumak, anlamak, anlanılanları koda döküp denemek ve buraya gelip paylaşmaktı.
Bu nedenle, kendi çözümümü paylaşmayacağım. Çünkü samimi bir çaba hissetmiyorum açıkçası.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
|